Следующий контент являются ответственными вопросами и ответами, данными после исходного набора вопросов интервью Java, и ответы были полностью пересмотрены. В исходных вопросах есть много дублирования и ценных вопросов, и многие ссылочные ответы также неверны. Модифицированный набор вопросов интервью Java относится к последней версии JDK, удаляет бесполезный контент, такой как EJB 2.x, и дополняет структуру данных и вопросы, связанные с алгоритмом, классические вопросы программирования интервью, крупный веб-сайт техническая архитектура, операционная система, база данных, тестирование программного обеспечения, паттерны дизайна, UML и другой контент. В то же время было глубоко проанализировано много знаний, такие как дизайн метода хэшкода, куча и генерация сбора мусора, новое параллельное программирование Java, Nio.2 и т. Д. Я считаю, что это будет полезно для программистов Java, которые готовятся присоединиться.
Java Programmer Wabtries Select (1-50)
1. Основы Java
1. Каковы аспекты объектно-ориентированных характеристик?
Ответ: Основные аспекты объектно-ориентированных функций:
1) Аннотация: абстракция - это процесс суммирования общих характеристик типа объекта в класс объектов, включая абстракцию данных и абстракцию поведения. Абстракция фокусируется только на том, какие атрибуты и поведение имеет объект, и не обращает внимания на то, каковы детали этого поведения.
2) Наследование: наследование - это процесс получения информации о наследовании из существующих классов и создания новых классов. Класс, который предоставляет унаследованную информацию, называется родительским классом (SuperClass, Base Class); Класс, который получает унаследованную информацию, называется подклассом (полученный класс). Наследование дает изменяющейся программной системе определенную степень непрерывности, а наследование также является важным средством инкапсулирования переменных факторов в программу (если вы не можете ее понять, пожалуйста, прочитайте часть режима моста в «Java and Patterns» или «шаблонах проектирования»).
3) Инкапсуляция: обычно считается, что инкапсуляция заключается в связывании данных с методом рабочих данных, а доступ к данным может быть достигнут только через определенное интерфейс. Суть объектно-ориентированного состоит в том, чтобы изобразить реальный мир как серию совершенно автономных и закрытых объектов. Метод, который мы пишем в классе, заключается в том, чтобы инкапсулировать детали реализации; Мы пишем класс, чтобы инкапсулировать данные и операции данных. Можно сказать, что упаковка состоит в том, чтобы скрыть все, что может быть скрыто, и предоставляет только простейший интерфейс программирования для внешнего мира (вы можете подумать о разнице между обычной стиральной машиной и полностью автоматической стиральной машиной. Очевидно, что полностью автоматическая стиральная машина упакована лучше и, следовательно, легче работать; смартфон, который мы используем сейчас, также достаточно хорошо упаковано, потому что некоторые кнопки могут справиться со всем).
4) Полиморфизм: полиморфизм относится к разрешению объектов разных подтипов по -разному реагировать на одно и то же сообщение. Проще говоря, это вызывает один и тот же метод с той же ссылкой на объект, но делайте разные вещи. Полиморфизмы делятся на полиморфизмы времени компиляции и полиморфизмы времени выполнения. Если метод объекта рассматривается как услуга, предоставляемая объектом для внешнего мира, то полиморфизм времени выполнения может быть объяснена как: когда система является доступом к услугам, предоставляемым системой B, система B имеет несколько способов предоставления услуг, но все прозрачно для системы A (точно так же, как электрическая бритва - это система A, его система питания является системой B, система B может быть основана на батареи или AC, и является то, что он может быть Solar Energy. Объекты, но он не знает, что такое базовая реализация системы питания и как она получает питание). Метод перегрузка реализует полиморфизм времени компиляции (также известный как предварительный), в то время как переопределение метода реализует полиморфизм времени выполнения (также известный как пост-связывание). Полиморфизм времени выполнения является наиболее важной вещью в объектно-ориентированной. Для реализации полиморфизма необходимо сделать две вещи: 1. Переписывание метода (подкласс наследует родительский класс и переписывает существующие или абстрактные методы в родительском классе); 2. Моделирование объекта (ссылаясь на объект типа дочернего типа с помощью ссылки на родительского типа, так что один и тот же ссылочный вызывает один и тот же метод, будет отображать различные поведения в соответствии с различными объектами подкласса).
2. В чем разница между доступом к модификаторам публично, частным, защищенным и не написанным (по умолчанию)?
Ответ: Различия следующие:
Прицел такой же, как и подкласс BUN.
public √ √ √ √ √ √
защищен √ √ √ ×
по умолчанию √ √ × ×
Приватный √ × × ×
По умолчанию по умолчанию, когда члены класса не записывают модификацию доступа. По умолчанию это эквивалентно публичному для других классов в том же пакете и частной для других классов, которые не находятся в одном пакете. Защищенный эквивалентен общественным субклассам и частным классам, которые не находятся в одном и том же пакете, которые не имеют отношения родителей и ребенка.
3. Является ли строка самым основным типом данных?
Ответ: Нет. В Java есть только 8 основных типов данных: байт, короткий, int, long, float, double, char и boolean; За исключением основного типа (примитивный тип) и типа перечисления (тип перечисления), остальные являются эталонными типами (ссылочный тип).
4. float f = 3,4; Это правильно?
Ответ: Неправильный. 3.4 - двойная точность. Присвоение двойного к типу с плавающей запятой (Float) вызовет потерю точности (внижение, также известное как сужение), поэтому вам необходимо отличить Float F = (float) 3.4; или написать float f = 3.4f;.
5. Короткий S1 = 1; S1 = S1 + 1; Есть что -нибудь не так? короткий S1 = 1; S1 += 1; Что -то не так?
Ответ: для короткого S1 = 1; S1 = S1 + 1; Поскольку 1 является типом INT, результатом работы S1+1 также является тип Int, и тип отливки требуется для назначения значения короткому типу. И короткий S1 = 1; S1 += 1; может быть скомпилирован правильно, потому что S1+= 1; эквивалентен S1 = (коротко) (S1 + 1); Есть неявные съемки.
6. Есть ли в Java Goto?
Ответ: GOTO - это зарезервированное слово в Java и не используется в текущей версии Java. (A list of Java keywords is given in the appendix of the book "The Java Programming Language" written by James Gosling (the father of Java) which includes goto and const, but these two are keywords that are currently unusable, so some places call it reserved words. In fact, the word reserved words should have a broader meaning, because programmers familiar with C language know that words or combinations of words that have special meanings used in the system library are considered зарезервированные слова)
7. В чем разница между Int и Integer?
Ответ: Java является почти чистым объектно-ориентированным языком программирования, но для удобства программирования он по-прежнему вводит основные типы данных, которые не являются объектами. Однако, чтобы использовать эти основные типы данных в качестве объектов, Java представила соответствующий класс обертки для каждого основного типа данных. Класс упаковки Int является целым числом. Со времен JDK 1.5 был введен автоматический механизм упаковки/распаковки, так что они могут быть преобразованы друг в друга.
Java предоставляет типы обертки для каждого примитивного типа:
Примитивные типы: логический, чар, байт, короткий, int, long, float, двойной
Типы упаковки: логический, персонаж, байт, короткий, целый ряд, длинные, плавучие, двойное
пакет com.lovo; // Зачем спрашивать о hovertree.compublic class autounboxingtest {public static void main (string [] args) {integer a = new Integer (3); Целое число B = 3; // Автоматическая коробка 3 в целое число типа int c = 3; System.out.println (a == b); // false Две ссылки не ссылаются на одну и ту же систему объектов.out.println (a == c); // true A автоматически раскакивается в тип int, а затем сравнивается с C}}Добавлено: Я недавно столкнулся с вопросом интервью, который также связан с автоматической упаковкой и распаком, код выглядит следующим образом:
открытый класс Test03 {public static void main (string [] args) {integer f1 = 100, f2 = 100, f3 = 150, f4 = 150; System.out.println (f1 == f2); System.out.println (f3 == f4); }} // hovertree.comЕсли вы этого не понимаете, легко думать, что оба выхода либо истины, либо ложь. Прежде всего, важно отметить, что четыре переменные F1, F2, F3 и F4 - все это целочисленные объекты, поэтому следующая операция сравнивает не значения, а ссылки. Какова суть упаковки? Когда мы назначаем значение int целочисленному объекту, мы будем называть статическое значение метода класса целого числа. Если мы посмотрим на исходный код значения, мы узнаем, что происходит.
public static integer value (int i) {if (i> = integerCache.low && i <= integerCache.high) return integerCache.cache [i + (-integerCache.low)]; вернуть новое целое число (i); } // hovertree.comIntegerCache - это внутренний класс целого числа, и его код выглядит так:
/** * Кэш для поддержки семантики идентификации объекта автобоксировки для значений между * -128 и 127 (включительно) в соответствии с требованиями JLS. * * Кэш инициализируется при первом использовании. Размер кэша * может управлять опцией {@code -xx: autoboxcachemax = <size>}. * Во время инициализации виртуальной машины Java.lang.integer.integercache.high свойство * может быть установлено и сохранено в свойствах частной системы в классе * sun.misc.vm. * hovertree.com */ private static class integercache {static final int low = -128; Статический финал int High; Статический конечный целочисленный кеш []; static {// высокое значение может быть настроено Property int h = 127; String integercachehighpropvalue = sun.misc.vm.getsavedproperty ("java.lang.integer.integercache.high"); if (integercachehighpropvalue! = null) {try {int i = parseint (integerCacheHighPropValue); i = math.max (i, 127); // максимальный размер массива IS integer.max_value h = math.min (i, integer.max_value -(-low) -1); } catch (numberFormateXception nfe) {// Если свойство не может быть проанализировано в int, игнорируйте его. }} high = h; cache = new Integer [(High - low) + 1]; int j = низкий; for (int k = 0; k <cache.length; k ++) cache [k] = новое целое число (j ++); // диапазон [-128, 127] должен быть интернализован (JLS7 5.1.7) Assert integerCache.high> = 127; } private integerCache () {}}Проще говоря, если буквальное значение превышает -128 и 127, то новый целочисленный объект не будет новым, но целочисленный объект в постоянном пуле будет непосредственно ссылаться. Следовательно, результат F1 == F2 в приведенном выше вопросе собеседования верно, и результат F3 == F4 является ложным. Чем проще вопросы интервью, тем больше есть загадка, и интервьюер должен иметь значительные навыки.
8. В чем разница между & и &&?
Ответ: Есть два использования оператора и оператора: (1) бить и (2) логично и. Оператор && является коротким замыканием и работой. Разница между логикой и коротким замыканием очень огромна, хотя оба требуют, чтобы логические значения на левом и правом конце оператора были верны значению всего выражения. && называется операцией короткого замыкания, потому что, если значение выражения слева от && является false, выражение справа будет напрямую охватывать, а операция не будет выполнена. Много раз нам может понадобиться использовать && вместо &. Например, при проверке того, что имя пользователя не является нулевым и не является пустой строкой, оно должно быть написано как: имя пользователя! Порядок этих двух не может быть обменен, и оператор нельзя использовать, потому что, если первое условие не верно, сравнение равных строки вообще не может быть выполнено, в противном случае будет сгенерировано нулевое месторождение. Примечание. То же самое относится и к разнице между логическим или оператором (|) и коротким замыканием или оператором (||).
Добавлено: Если вы знакомы с JavaScript, вы можете почувствовать силу короткометражных вычислений. Если вы хотите стать мастером JavaScript, начните с игры на короткие вычисления.
9. Объясните использование стека, кучи и статических областей хранения в памяти.
Ответ: Обычно мы определяем переменную базового типа данных, ссылку на объект и хранилище функций на месте. Все используют пространство стека в памяти; и объекты, созданные с помощью нового ключевого слова и конструктора, размещены в пространстве кучи; Литералы в программе, такие как 100, «Привет» и константы, написанные непосредственно, находятся в статической области хранения. Пространство стека работает самым быстрым, но также очень маленьким. Обычно большое количество объектов помещается в пространство кучи, и вся память, включая виртуальную память на жестком диске, может использоваться в качестве места кучи.
String str = new String ("hello");
В приведенном выше утверждении STR помещается в стек, строковый объект, созданный с новым, размещен на куче, а буквальный «Hello» находится на статической области хранения.
Дополнение: более новая версия Java использует технологию, называемую «анализом побега», которая может поместить некоторые локальные объекты в стек для повышения эксплуатационной производительности объектов.
10. Что такое Math.Round (11,5), равной? Что такое Math.Round (-11,5), равной?
Ответ: возвращаемое значение Math.Round (11.5) составляет 12, а возвратное значение математики. Раунд (-11,5) --11. Принцип округления состоит в том, чтобы добавить 0,5 к параметру, а затем округлить его.
11. Может ли SWTICH действовать на байт, длинный акт на строку?
Ответ: В раннем JDK, в Switch (Expr) Expr может быть байт, короткий, чар и инт. Начиная с версии 1.5, Java представила типы enum (enums), а Expr также может быть перечислен, начиная с версии 1.7 JDK, а также строки (строка). Длинный тип не допускается.
12. Используйте наиболее эффективный метод для расчета 2 раза 8?
Ответ: 2 << 3 (перемещение 3 бита слева эквивалентно умножению на 2 на мощность 3, а перемещение 3 бита справа эквивалентно делениям на 2 на силу 3).
Дополнение: Когда мы переписываем метод хэшкода для класса, который мы написали, мы можем увидеть код, показанный ниже. На самом деле, мы не совсем понимаем, почему мы используем такое умножение для генерации хэш -кода (хэш -код), и почему это число является основным номером, и почему обычно выбирается число 31? Вы можете Baidu по ответам на первые два вопроса. Выберите 31, потому что вместо умножения можно использовать операции смены и вычитания, тем самым достигая лучшей производительности. Говоря об этом, вы, возможно, подумали о: 31 * num <==> (num << 5) - num, смещение левых 5 битов эквивалентно умножению на 2 на 5 -й мощность (32), а вычитание самого эквивалентно умению на 31. Все виртуальные машины могут автоматически завершить эту оптимизацию.
Пакет com.loonstudio; Public Class Phonenumber {Private Int Area Code; Private String Prefix; Частный струнный бегняк; @Override public int hashcode () {final int prime = 31; int result = 1; result = prime * result + reaircode; result = prime * result + ((LineNumber == null)? 0: lineNumber.hashcode ()); result = prime * result + ((prefix == null)? 0: prefix.hashcode ()); результат возврата; } @Override public boolean equals (Object obj) {if (this == obj) вернуть true; if (obj == null) вернуть false; if (getClass ()! = obj.getClass ()) вернуть false; Phonenumber fore = (phonenumber) obj; if (reacycode! = Другой. areacode) вернуть false; if (lineNumber == null) {if (shry.lineNumber! = null) вернуть false; } else if (! lineNumber.equals (ore.lineNumber)) вернуть false; if (prefix == null) {if (ore.prefix! = null) вернуть false; } else if (! prefix.equals (ore.prefix)) вернуть false; вернуть истину; }} // Зачем спрашивать о Hovertree.com13. Есть ли метод длины () для массивов? Есть ли метод длины () для строки?
Ответ: массив не имеет метода длины (), но имеет атрибут длины. Строка имеет метод длины (). В JavaScript получение длины строки получается через атрибут длины, который легко путать с Java.
14. На Java, как вырваться из текущих многочисленных вложенных петлей?
Ответ: добавьте отметку, такую как перед самой внешней петлей, а затем используйте разрыв; Многочисленные петли могут быть сломаны. (Java поддерживает Tagged Break и продолжайте операторы, и их функции немного похожи на операторы GOTO в C и C ++, но, как и избежать GOTO, вы должны избегать перерыва с меткой и продолжать, потому что она не сделает вашу программу более элегантной, и часто даже имеет противоположный эффект, поэтому этот синтаксис на самом деле лучше.).
15. Можно ли переопределить конструктор?
Ответ: конструктор не может быть унаследован, поэтому его нельзя переписано, но его можно перегрузить.
16. Два объекта имеют одинаковое значение (x.equals (y) == true), но они могут иметь разные хэш -коды. Это верно?
Ответ: Нет, если два объекта x и y удовлетворяют x.equals (y) == true, их хэш -код должен быть одинаковым. Java предусматривает метод Eqauls и метод хэшкода следующим образом: (1) Если два объекта одинаковы (Equal Method возвращает True), то их значения хэшкода должны быть одинаковыми; (2) Если хэшкоды двух объектов одинаковы, они не обязательно одинаковы. Конечно, вам не нужно делать по мере необходимости, но если вы нарушаете приведенные выше принципы, вы обнаружите, что при использовании контейнеров тот же объект может появляться в сборе наборах, и эффективность добавления новых элементов будет значительно снижена (для систем, использующих хэш -хранение, частые конфликты в хэш -кодах приведут к резкому снижению доступа).
Приложение: Многие программы Java знают о равенстве и методах хэшкода, но многие люди просто знают это. В шедевре Джошуа Блоха «Эффективная Java» (многие компании-разработчики, «эффективная Java», «Мысли по программированию Java» и «Рефакторинг: улучшение качества существующего кода»-это обязательные книги программистов Java. Если вы не читаете его, торайте и покупайте один на Amazon.) Это то, как ввести метод Equals: первый метод Equals. Верно) и симметрия (x.equals (y) возвращает true, y.equals (x) также должна быть вернуть True), транзит (x.equals (y) и y.ecals (z) также должны возвращать True) и согласованность (когда информация о объекте, на которые ссылается x и y, не изменяются, множественные вызовы x equals (y) должны получить то же самое возвращаемое значение), и для любого n-null spettiper x, null x. equals (y) должен получить то же самую версию), и для любого n-null spettile x, null x. equals (y). Уловки для реализации высококачественных методов равны включают в себя: 1. Используйте оператор ==, чтобы проверить, является ли параметр ссылкой на этот объект »; 2. Используйте оператор экземпляра, чтобы проверить, является ли параметр правильным типом »; 3. Для атрибутов ключей в классе проверьте, соответствуют ли атрибуты объекту; 4. После написания метода равных, спросите себя, удовлетворяет ли он симметрией, транзит и последовательности; 5. Всегда переписывайте хешкод, когда переписывание равняется; 6. Не заменяйте объект объекта в параметрах метода equals на другие типы и не забывайте аннотацию @Override при переписывании.
17. Можно ли унаследовать класс строки?
Ответ: класс строки является окончательным классом и не может быть унаследован.
Дополнение: наследственная строка сама по себе является неправильным поведением. Лучший способ повторного использования типов строк-это ассоциация (HAS-A), а не наследование (IS-A).
18. Когда объект передается в качестве параметра методу, этот метод может изменить свойства объекта и вернуть измененный результат. Так это проход значения или справочный проход здесь?
Ответ: это передача стоимости. Язык программирования Java проходит только параметры со значениями. Когда экземпляр объекта передается в метод в качестве параметра, значение параметра является ссылкой на объект. Свойства объекта можно изменить во время процесса вызова, но ссылка на объект никогда не изменится. В C ++ и C#значение пройденных параметров может быть изменено путем передачи ссылок или передачи параметров.
Дополнение: действительно неудобно не передавать ссылки в Java, которая не была улучшена в Java 8. Именно таким образом в коде, написанном в Java, большое количество классов обертки (размещение ссылок, которые необходимо изменить с помощью вызовов метода в класс обертывания, а затем передавая объект Wrapper в метод). Этот подход будет только раздутым кодом, особенно для разработчиков, которые превращаются из C и C ++ в Java -программисты в невыносимость.
19. В чем разница между String и StringBuilder и StringBuffer?
Ответ: Платформа Java предоставляет два типа строк: String и StringBuffer/StringBuilder, которые могут хранить и манипулировать строками. Где строка является строкой только для чтения, что означает, что содержимое строки, на которую ссылается строка, не может быть изменено. Строковые объекты, представленные классами StringBuffer и StringBuilder, могут быть изменены напрямую. StringBuilder был введен в JDK 1.5. Он точно такой же, как метод StringBuffer, разница в том, что он используется в одной резьбе, потому что все его аспекты не изменяются с помощью синхронизированного, поэтому он немного более эффективен, чем StringBuffer.
Приложение 1: Есть вопрос интервью: есть ли какая -либо ситуация, когда использование + для выполнения строковой конкатенации лучше, чем называть метод добавления объекта StringBuffer/StringBuilder? Если строка, полученная после подключения, уже существует в области статического хранения, то использование + для строковой конкатенации лучше, чем метод добавления StringBuffer/StringBuilder.
Дополнение 2: Следующий также представляет собой вопрос об интервью, запрашивая результаты программы, чтобы увидеть, сможете ли вы дать правильный ответ.
пакет com.lovo; // Зачем спрашивать о hovertree.compublic class stringequestest {public static void main (string [] args) {String a = "Programming"; String b = new String ("Программирование"); Строка C = "программа" + "ming"; System.out.println (a == b); System.out.println (a == c); System.out.println (A.Equals (b)); System.out.println (A.Equals (C)); System.out.println (A.Intern () == B.Intern ()); }}20. Разница между перегрузкой и переопределением. Можно ли различать перегруженные методы на основе типа возврата?
Ответ: как перегрузка, так и переписывание метода - это способы реализации полиморфизма. Разница в том, что первый реализует полиморфизм времени компиляции, в то время как последний реализует полиморфизм времени выполнения. Перегрузка происходит в классе. Если метод с одинаковым именем имеет другой список параметров (разные типы параметров, различное количество параметров или обоих), он считается перегрузкой; Перезапись происходит между подклассом и родительским классом. Перезапись требует, чтобы переписанный метод подкласса и родительский класс имел тот же тип возврата, что и переписанный метод родительского класса, который является лучшим доступом, чем переписанный метод родительского класса, и не может объявить больше исключений, чем переписанный метод родительского класса (Принцип замены Риска). Перегрузка не имеет особых требований для типов возврата.
Приложение: Huawei Однажды задал вопрос в вопросе интервью: Почему вы не можете различить перегрузку на основе типа возврата и сказать свой ответ!
21. Опишите принцип и механизм файлов класса загрузки JVM?
Ответ: Загрузка классов в JVM реализована классовым загрузчиком (ClassLoader) и его подклассами. Загрузчик класса в Java является важным компонентом системы выполнения Java, который отвечает за поиск и загрузку классов в файлах класса во время выполнения.
Пополнить:
1. Из-за кроссплатформенного характера Java, скомпилированная программа Java Source Source является не исполняемой программой, а одним или несколькими файлами класса. Когда программа Java должна использовать класс, JVM гарантирует, что класс был загружен, подключен (проверен, подготовлен и анализ) и инициализирован. Загрузка класса относится к чтению данных из файла класса .class в память. Обычно создание байтового массива для чтения его в файл .class, а затем генерируя объект класса, соответствующий загруженному классу. После завершения загрузки объект класса по -прежнему остается неполным, поэтому класс недоступен в настоящее время. Когда класс загружен, он входит на стадию соединения. Этот этап включает в себя три шага: проверка, подготовка (выделение памяти для статических переменных и настройка начального значения по умолчанию) и анализ (замените ссылки на символы на прямые ссылки). Наконец, JVM инициализирует класс, в том числе: 1. Если у класса есть прямой родительский класс, а класс не был инициализирован, то родительский класс будет инициализирован сначала; 2. Если в классе есть операторы инициализации, эти операторы инициализации будут выполнены по очереди.
2. Загрузка класса выполняется с помощью загрузчика класса, который включает в себя: root Loader (Bootstrap), расширение загрузчика (расширение), системный загрузчик (система) и пользовательский загрузчик класса (подкласс Java.lang.classloader). Начиная с JDK 1.2, процесс загрузки класса принимает механизм делегирования отца (PDM). PDM лучше обеспечивает безопасность платформы Java. В этом механизме собственная начальная загрузка JVM является корневым погрузчиком, а другие погрузчики имеют только один родительский класс. Загрузка класса, запрашивая, запрашивает загрузчик родительского класса для загрузки, а загрузчик родительского класса будет загружен только подклассовым погрузчиком, когда он бессилен. JVM не дает ссылки на начальную загрузку на программы Java. Вот несколько инструкций для нескольких погрузчиков класса:
A) начальная загрузка: обычно реализуется с использованием локального кода и отвечает за загрузку базовой библиотеки класса Core Class JVM (RT.JAR);
б) Расширение: загрузите библиотеку классов из каталога, указанного в системе java.ext.dirs, а ее родительский погрузчик является начальной загрузкой;
C) Система: также известная как загрузчик класса приложения, его родительский класс - расширение. Это наиболее широко используемый загрузчик класса. Он записывает классы из каталога, указанного с переменной среды ClassPath или атрибута системы java.class.path, и является родительским загрузчиком по умолчанию пользовательского загрузчика.
22. Можно ли хранить китайский символ в переменной типа Char? Почему?
Ответ: Тип Char может хранить китайский символ, потому что кодирование, используемое в Java, является Unicode (не выбрано конкретное кодирование, а символы непосредственно используются в номере набора символов, который является единственным унифицированным методом). Тип ChAR занимает 2 байта (16 -битный), поэтому не так уж и проблем с тем, чтобы положить китайцев.
Дополнение: Использование Unicode означает, что символы имеют разные проявления внутри и за пределами JVM и оба являются Unicode внутри JVM. Когда этот символ переносится из JVM снаружи (например, хранится в файловой системе), требуется преобразование кодирования. Таким образом, Java имеет байтовые потоки и потоки символов, а также потоки преобразования, которые преобразуют между потоками символов и байтовыми потоками, такими как InputStreamReader и OutputStreamReader. Эти два класса представляют собой классы адаптера между байтовыми потоками и потоками символов, и выполняют задачу кодирования преобразования; Для программистов C, чтобы завершить такое преобразование кодирования, они, вероятно, полагаются на характеристики общей памяти Union (Union/Community) для достижения.
23. Каковы сходства и различия между абстрактным классом и интерфейсом?
Ответ: как абстрактные классы, так и интерфейсы не могут быть созданы, но ссылки на абстрактные классы и типы интерфейсов могут быть определены. Если класс наследует абстрактный класс или реализует интерфейс, ему необходимо реализовать все абстрактные методы в нем, в противном случае класс все еще должен быть объявлен как абстрактный класс. Интерфейсы более абстрактные, чем абстрактные классы, потому что конструкторы могут быть определены в абстрактных классах, и могут быть абстрактные методы и конкретные методы, в то время как конструкторы не могут быть определены в интерфейсах, и все методы в них являются абстрактными методами. Участники абстрактных классов могут быть частными, дефолтными, защищенными и публичными, в то время как участники интерфейсов все общедоступны. Переменные члена могут быть определены в абстрактных классах, в то время как переменные -члены, определенные в интерфейсах, на самом деле являются постоянными. Занятия с абстрактными методами должны быть объявлены как абстрактные классы, а абстрактные классы не обязательно имеют абстрактные методы.
24. В чем разница между статическими вложенными классами и внутренними классами (внутренний класс)?
Ответ: Статический вложенный класс - это внутренний класс, объявленный статичным, который может быть создан экземпляр, не полагаясь на экземпляры внешнего класса. Обычные внутренние классы должны быть созданы после создания внешнего класса, а синтаксис выглядит довольно странно, как показано ниже.
пакет com.lovo; / ** * Покерный класс (колода покера) Зачем спрашивать о Hovertree.com * */ Public Class Poker {Private Static String [] Suites = {"Spade", "Rose", "Grass Flower", "Cube"}; Частный статический int [] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; частная карта [] карты; / *** Конструктор**/ public poker () {cards = новая карта [52]; for (int i = 0; i <suites.length; i ++) {for (int j = 0; j <faces.length; j ++) {карты [i * 13+j] = новая карта (Suites [i], faces [j]); }}} / ** * shuffle (случайный вне порядка) * * / public void shuffle () {for (int i = 0, len = cards.length; i <len; i ++) {int index = (int) (math.random () * len); Карта temp = card [index]; карты [index] = cards [i]; карты [i] = temp; }} / *** Card Deal* @param Индекс позиции сделки** / public card deal (int index) {return card [index]; } / ** * Card Class (кусок покера) * [внутренний класс] * @author luo hao * * / public class card {private String Suite; // подчиняться частному лицу; // указывает Public Card (String Suite, int face) {this.suite = suite; this.face = face; } @Override public String toString () {string faceStr = ""; Switch (face) {case 1: facestr = "a"; перерыв; Случай 11: facestr = "j"; перерыв; Случай 12: facestr = "q"; перерыв; Случай 13: FACESTR = "k"; перерыв; по умолчанию: facestr = string.valueof (face); } return Suite + Facesr; }}} Тестовый класс:
пакет com.lovo; класс pokertest {public static void main (string [] args) {poker poker = new Poker (); poker.shuffle (); // shuffle poker.card c1 = poker.deal (0); // обслуживает первую карту // для нестатических карт внутренних классов // может быть создан объект карты только через свой внешний класс покерный объект Poker.card C2 = poker.new card ("Red Heart", 1); // Создать карту самостоятельно System.out.println (C1); // первая система.out.println (C2); // Печать: Red Heart A}} // Зачем спрашивать о Hovertree.com25. Будет ли утечка памяти в Java? Пожалуйста, опишите это кратко.
Ответ: Теоретически, у Java не будет утечек памяти, потому что у нее есть механизм сбора мусора (GC) (это также важная причина, по которой Java широко используется в программировании на стороне сервера); Однако в реальной разработке могут быть бесполезны, но доступные объекты, и эти объекты не могут быть переработаны с помощью GC, и возникнут утечки памяти. Примером является то, что объекты в сеансе Hibernate (кеш первого уровня) постоянны, и сборщик мусора не будет перерабатывать эти объекты, но в этих объектах могут быть бесполезные мусорные объекты. В следующем примере также показана утечка памяти в Java:
пакет com.lovo; // Зачем спрашивать о hovertree.comimport java.util.arrays; импортировать java.util.emptystackexception; открытый класс mystack <t> {private t [] elements; private int size = 0; Частный статический конечный int init_capacity = 16; public mystack () {elements = (t []) новый объект [init_capacity]; } public void push (t elem) {eveRecapacity (); Элементы [размер ++] = elem; } public t pop () {if (size == 0) бросить новый emptystackexception (); возвращаемые элементы [-размер]; } private void ensureCapacity() { if(elements.length == size) { elements = Arrays.copyOf(elements, 2 * size + 1); }}}上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError。
26、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
27、静态变量和实例变量的区别?
答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。在Java开发中,上下文类和工具类中通常会有大量的静态成员。
28、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?
答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,因此在调用静态方法时可能对象并没有被初始化。
29、如何实现对象克隆?
答:有两种方式:
1.实现Cloneable接口并重写Object类中的clone()方法;
2.实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。
package com.lovo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class MyUtil { private MyUtil() { throw new AssertionError(); } public static <T> T clone(T obj) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bout); oos.writeObject(obj); ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bin); return (T) ois.readObject(); // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义// 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源} } //何问起hovertree.com下面是测试代码:
package com.lovo; import java.io.Serializable; /** * Human* @author Luo Hao* */ class Person implements Serializable { private static final long serialVersionUID = -9102017020286042305L; Приватное название строки; // Name private int age; // Age private Car car; // Car public Person(String name, int age, Car car) { this.name = name; this.age = возраст; this.car = car; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", car=" + car + "]"; } } /** * Car class* @author Luo Hao* */ class Car implements Serializable { private static final long serialVersionUID = -5713945027627603702L; private String brand; // Brand private int maxSpeed; // Top speed public Car(String brand, int maxSpeed) { this.brand = brand; this.maxSpeed = maxSpeed; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]"; } } //Why ask about hovertree.comclass CloneTest { public static void main(String[] args) { try { Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300)); Person p2 = MyUtil.clone(p1); // Deep cloning p2.getCar().setBrand("BYD"); // Modify the brand attributes of the cloned Person object p2-associated car object// The original Person object p1-associated car will not be affected in any way// Because when cloning Person object, the car object associated with it is also cloned System.out.println(p1); } catch (Exception e) { e.printStackTrace(); }}}注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。
30、GC 是什么?为什么要有GC?
答: GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得iOS的系统比Android系统有更好的用户体验,其中一个深层次的原因就在于Android系统中垃圾回收的不可预知性。
补充:垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:
伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。
幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。
终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。
与垃圾回收相关的JVM参数:
-Xms / -Xmx --- 堆的初始大小/ 堆的最大大小
-Xmn --- 堆中年轻代的大小
-XX:-DisableExplicitGC --- 让System.gc()不产生任何作用
-XX:+PrintGCDetail --- 打印GC的细节
-XX:+PrintGCDateStamps --- 打印GC操作的时间戳
31、String s=new String(“xyz”);创建了几个字符串对象?
答:两个对象,一个是静态存储区的"xyz",一个是用new创建在堆上的对象。
32、接口是否可继承(extends)接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)?
答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承具体类,但前提是具体类必须有明确的构造函数。
33、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?
答:可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。
34、Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
答:可以继承其他类或实现其他接口,在Swing编程中常用此方式来实现事件监听和回调。
35、内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。
36、Java 中的final关键字有哪些用法?
答: (1)修饰类:表示该类不能被继承;(2)修饰方法:表示方法不能被重写;(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
37、指出下面程序的运行结果:
class A{ static{ System.out.print("1"); } public A(){ System.out.print("2"); } } class B extends A{ static{ System.out.print("a"); } public B(){ System.out.print("b"); } } //Why ask about hovertree.compublic class Hello{ public static void main(String[] args){ A ab = new B(); ab = new B(); }}答:执行结果:1a2b2b。创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。
38、数据类型之间的转换:
1)如何将字符串转换为基本数据类型?
2)如何将基本数据类型转换为字符串?
отвечать:
1)调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型;
2)一种方法是将基本数据类型与空字符串(””)连接(+)即可获得其所对应的字符串;另一种方法是调用String 类中的valueOf(…)方法返回相应字符串
39、如何实现字符串的反转及替换?
答:方法很多,可以自己写实现也可以使用String或StringBuffer / StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:
public static String reverse(String originStr) { if(originStr == null || originStr.length() <= 1) return originStr; return reverse(originStr.substring(1)) + originStr.charAt(0); } //何问起hovertree.com40、怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
答:代码如下所示:
String s1 = "你好";String s2 = newString(s1.getBytes("GB2312"), "ISO-8859-1");41、日期和时间:
1)如何取得年月日、小时分钟秒?
2)如何取得从1970年1月1日0时0分0秒到现在的毫秒数?
3)如何取得某月的最后一天?
4)如何格式化日期?
答:操作方法如下所示:
1)创建java.util.Calendar 实例,调用其get()方法传入不同的参数即可获得参数所对应的值
2)以下方法均可获得该毫秒数:
Calendar.getInstance().getTimeInMillis(); System.currentTimeMillis(); //何问起hovertree.com
3)示例代码如下:
Calendar time = Calendar.getInstance(); time.getActualMaximum(Calendar.DAY_OF_MONTH); //何问起hovertree.com
4)利用java.text.DataFormat 的子类(如SimpleDateFormat类)中的format(Date)方法可将日期格式化。
42、打印昨天的当前时刻。
отвечать:
public class YesterdayCurrent { public static void main(String[] args){ Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); System.out.println(cal.getTime()); } } //何问起hovertree.com43、比较一下Java 和JavaSciprt。
答: JavaScript 与Java是两个公司开发的不同的两个产品。Java 是原Sun 公司推出的面向对象的程序设计语言,特别适合于互联网应用程序开发;而JavaScript是Netscape公司的产品,为了扩展Netscape浏览器的功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释性语言,它的前身是LiveScript;而Java 的前身是Oak语言。
下面对两种语言间的异同作如下比较:
1)基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用;
2)解释和编译:Java 的源代码在执行之前,必须经过编译;JavaScript 是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行;
3)强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是解释器在运行时检查其数据类型;
4)代码格式不一样。
补充:上面列出的四点是原来所谓的标准答案中给出的。其实Java和JavaScript最重要的区别是一个是静态语言,一个是动态语言。目前的编程语言的发展趋势是函数式语言和动态语言。在Java中类(class)是一等公民,而JavaScript中函数(function)是一等公民。对于这种问题,在面试时还是用自己的语言回答会更加靠谱。
44、什么时候用assert?
答: assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后, assertion检查通常是关闭的。在实现中,断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式计算为false,那么系统会报告一个AssertionError。
断言用于调试目的:
assert(a > 0); // throws an AssertionError if a <= 0
断言可以有两种形式:
assert Expression1;
assert Expression1 : Expression2 ;
Expression1 应该总是产生一个布尔值。
Expression2 可以是得出一个值的任意表达式;这个值用于生成显示更多调试信息的字符串消息。
断言在默认情况下是禁用的,要在编译时启用断言,需使用source 1.4 标记:
javac -source 1.4 Test.java
要在运行时启用断言,可使用-enableassertions 或者-ea 标记。
要在运行时选择禁用断言,可使用-da 或者-disableassertions 标记。
要在系统类中启用断言,可使用-esa 或者-dsa 标记。还可以在包的基础上启用或者禁用断言。可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。
45、Error 和Exception 有什么区别?
答: Error 表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;Exception 表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。
Supplement: During the interview with Motorola in 2005, I asked a question like "If a process reports a stack overflow run-time error, what's the most possible cause?", giving four options a. lack of memory; беременный write on an invalid memory space; в recursive function calling; дюймовый array index out of boundary. Java programs may also encounter StackOverflowError when running. This is an error that cannot be recovered, so I can only re-modify the code. The answer to this interview question is c. If you write recursion that cannot converge quickly, it is very likely to cause a stack overflow error, as shown below:
package com.lovo; public class StackOverflowErrorTest { public static void main(String[] args) { main(null); } } //何问起hovertree.com因此,用递归编写程序时一定要牢记两点:1. 递归公式;2. 收敛条件(什么时候就不再递归而是回溯了)。
46、try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
答:会执行,在方法返回调用者前执行。Java允许在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,这会对程序造成很大的困扰,C#中就从语法上规定不能做这样的事。
47、Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?
答: Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java 中,每个异常都是一个对象,它是Throwable 类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java 的异常处理是通过5 个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throw)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;try用来指定一块预防所有“异常”的程序;catch 子句紧跟在try块后面,用来指定你想要捕捉的“异常”的类型;throw 语句用来明确地抛出一个“异常”;throws用来标明一个成员函数可能抛出的各种“异常”;finally 为确保一段代码不管发生什么“异常”都被执行一段代码;可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try 语句,“异常”的框架就放到栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种“异常”进行处理,栈就会展开,直到遇到有处理这种“异常”的try 语句。
48、运行时异常与受检异常有何异同?
答:异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。异常和继承一样,是面向对象程序设计中经常被滥用的东西,神作《Effective Java》中对异常的使用给出了以下指导原则:
不要将异常处理用于正常的控制流(设计良好的API不应该强迫它的调用者为了正常的控制流而使用异常)
对可以恢复的情况使用受检异常,对编程错误使用运行时异常避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常的发生)
优先使用标准的异常每个方法抛出的异常都要有文档保持异常的原子性不要在catch中忽略掉捕获到的异常
49、列出一些你常见的运行时异常?
отвечать:
ArithmeticException(算术异常)
ClassCastException (类转换异常)
IllegalArgumentException (非法参数异常)
IndexOutOfBoundsException (下表越界异常)
NullPointerException (空指针异常)
SecurityException (安全异常)
50、final, finally, finalize 的区别?
答: final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final 的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final 的方法也同样只能使用,不能在子类中被重写。finally:通常放在try…catch的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。finalize:Object类中定义的方法,Java中允许使用finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize() 方法可以整理系统资源或者执行其他清理工作。
Выше всего содержание этой статьи. I hope it will be helpful to everyone in the Java interview, and I hope everyone will support Wulin.com more.