Давайте сначала взглянем на интеллект-карту этой статьи, и я объясню следующее содержание.
Начнем нашу статью.
Обзор Java
Что такое Ява?
Java была впервые выпущена компанией Sun Microsystems в 1995 году.编程语言
и вычислительные платформы. Язык программирования относительно прост для понимания, так что计算平台
Шерстяная ткань?
Вычислительная платформа — это среда, в которой на компьютере выполняются приложения (программное обеспечение), в том числе
硬件环境
и软件环境
. Общая системная платформа включает аппаратную архитектуру, операционную систему и библиотеку времени выполнения компьютера.
Java — это быстро, безопасно и надежно. От ноутбуков до центров обработки данных, от игровых приставок до научных суперкомпьютеров, от мобильных телефонов до Интернета — Java везде! Java в основном делится на три версии
- JavaSE (J2SE) (стандартная версия платформы Java2, стандартная версия платформы Java)
- JavaEE (J2EE) (платформа Java 2, Enterprise Edition, Java Platform Enterprise Edition)
- JavaME (J2ME) (Java 2 Platform Micro Edition, микровыпуск платформы Java).
Особенности Java
- Ява — это
面向对象
язык программирования
Что такое объектная ориентация?面向对象(Object Oriented)
Это идея разработки программного обеспечения. Это абстракция реального мира, и объектно-ориентированная система организует связанные данные и методы как единое целое.
Другой идеей развития является процессно-ориентированная идея развития.面向过程(Procedure Oriented)
Это процессно-ориентированная идея программирования. Например: Например, вы студент, сколько вещей вам нужно делать каждый день, чтобы ходить в школу?
Вставай, одевайся, умойся и почисти зубы, поешь, иди в школу. Обычно ряд действий выполняется последовательно.
class student {
void student_wakeUp(){...}
void student_cloth(){...}
void student_wash(){...}
void student_eating(){...}
void student_gotoSchool(){...}
}
А объектно-ориентированный подход может абстрагировать учащихся, поэтому этот пример станет
class student(){
void wakeUp(){...}
void cloth(){...}
void wash(){...}
void eating(){...}
void gotoSchool(){...}
}
Каждое действие может выполняться не в строгом порядке. Это особенность номер один.
- Java отказывается от концепций множественного наследования, указателей, управления памятью и т. д., которые трудно понять в C++, нет необходимости вручную управлять жизненным циклом объектов, что является второй особенностью.
- Язык Java имеет две характеристики: мощные функции и простота использования.Сейчас разработка на уровне предприятия, быстрая и гибкая разработка, особенно появление различных фреймворков, делают Java все более и более популярным языком. Это особенность номер три.
- Java – это статический язык. Под статическим языком понимается язык, который может знать тип данных во время компиляции и может проверять правильность типа перед запуском. После того как тип определен, его нельзя изменить, как в следующем примере.
public void foo() {
int x = 5;
boolean b = x;
}
Статические языки в основномPascal, Perl, C/C++, JAVA, C#, ScalaЖдать.
Соответственно, в динамических языках нет конкретной ситуации, требующей указания типа переменной, типа данных, определяемого во время выполнения. Например, есть **Lisp, Perl, Python, Ruby, JavaScript** и так далее.
По замыслу все языки предназначены для преобразования удобочитаемого кода в машинные инструкции. Динамические языки предназначены для того, чтобы программисты могли писать код более эффективно, поэтому вы можете реализовать функциональность с меньшим количеством кода. Статические языки предназначены для более эффективной работы оборудования, поэтому от программистов требуется писать точный код, чтобы ваш код выполнялся как можно быстрее. С этой точки зрения эффективность выполнения статического языка выше и быстрее, чем у динамического языка. Это особенность номер четыре.
- Java является платформенно-независимой и переносимой.
У Java есть очень известный слоган:Write once, run anywhere
, то есть один раз пиши, беги везде. Почему Java может использовать такой бредовый лозунг? ядроJVM
. Мы знаем, что многие детали защищены между компьютерными приложениями и аппаратным обеспечением, и они полагаются на операционную систему для завершения планирования и координации.Общая архитектура выглядит следующим образом.
Тогда архитектура Java-приложения и JVM станет следующей
Java является кроссплатформенной, и скомпилированные Java-программы могут работать на любой платформе с JVM. Вы можете написать код на платформе Windows, а затем заставить его работать на платформе Linux.Как это сделать?
Сначала вам нужно написать код Java в своем приложении;
использоватьEclipse
илиjavac
Скомпилируйте код Java для.class
документ;
Затем введите файл .class как.jar
документ;
Тогда ваш файл .jar может работать под Windows, Mac OS X, Linux. Разные операционные системы имеют разные реализации JVM, поэтому при смене платформы вам не нужно заново компилировать код Java. Это особенность пять.
- Java может легко реализовать многопоточность
Java — это язык высокого уровня, а языки высокого уровня ограждают пользователей от множества низкоуровневых деталей реализации. Например, как Java реализует многопоточность. С точки зрения операционной системы в основном существуют следующие способы достижения многопоточности.
Реализация многопоточности в пользовательском пространстве
Реализация многопоточности в пространстве ядра
Смешанная реализация потоков в пространстве пользователя и ядра
И я думаю, что Java должна быть в用户空间
Реализована многопоточность, ядро не знает о существовании механизма многопоточности в Java. Это особенность шесть.
- Java имеет высокую производительность
Код, который мы пишем, скомпилированный компилятором javac, называется字节码(bytecode)
, байт-код преобразуется в машинный код интерпретатором, встроенным в JVM, который интерпретируется и выполняется, и этот процесс преобразования менее эффективен. Но некоторые реализации JVM, такие какHotspot JVM
при условииJIT(Just-In-Time)
Компилятор, также известный как динамический компилятор, JIT может компилировать горячий код в машинный код во время выполнения.Этот метод более эффективен, то есть выполнение компиляции. Итак, Java — это не просто интерпретируемый язык. Это особенность семь.
- Язык Java надежен
Механизм строгого типа Java, обработка исключений, автоматическая сборка мусора и т. д. являются важными гарантиями надежности программ Java. Это также важное различие между языком Java и C. Это особенность восемь.
- Java упрощает разработку распределенных проектов
Язык Java поддерживает разработку интернет-приложений.В Java есть net api, который предоставляет библиотеки классов для программирования сетевых приложений, включая URL, URLConnection, Socket, ServerSocket и т. д. ЯваRMI(远程方法激活)
Механизм также является важным средством разработки распределенных приложений. Это функция девять.
Среда разработки Java
JDK
JDK(Java Development Kit)
Известный как Java Development Kit или Java Development Tool, это среда разработки программ для написания Java-апплетов и приложений. JDK — это ядро всей Java, включаяJava运行环境(Java Runtime Environment)
,НемногоJava 工具
иJava 的核心类库(Java API)
.
Мы можем серьезно взглянуть на эту диаграмму, она включает в себя почти все концепции Java, которые я используюjdk1.8
, вы можете нажатьDescription of Java Conceptual Diagram
, вы можете обнаружить, что это включает в себя все описания Java
Oracle предоставляет две реализации платформы Java: одна — JDK, о которой мы упоминали выше, стандартный инструментарий разработки Java, а другая — JRE, называемая Java Runtime Environment, Java Runtime Environment. JDK намного функциональнее, чем JRE.
JRE
JRE — это среда выполнения, а JDK — среда разработки. Поэтому при написании программ на Java требуется JDK, а при запуске программ на Java требуется JRE. JDK уже содержит JRE, поэтому, пока JDK установлен, вы можете редактировать программу Java и запускать программу Java в обычном режиме. Однако, поскольку JDK содержит много контента, не связанного с запуском, он занимает много места, поэтому для запуска обычных Java-программ не требуется устанавливать JDK, а требуется только установка JRE.
Конфигурация среды разработки Java
Об этом месте больше нечего сказать, в Интернете есть много обучающих материалов по настройке для ознакомления.
Базовый синтаксис Java
После настройки среды разработки Java и загрузки средств разработки Java (Eclipse, IDEA и т. д.) вы можете писать код Java.Поскольку в этой статье рассматривается система Java с нуля, необходимо начать с основных понятий.
тип данных
В Java типы данных только四类八种
- Целочисленный тип: byte, short, int, long
Байт также является байтом, 1 байт = 8 бит, значение байта по умолчанию равно 0;
short занимает два байта, то есть 16 бит, 1 short = 16 бит, и его значение по умолчанию также равно 0;
int занимает четыре байта, то есть 32 бита, 1 int = 32 бита, значение по умолчанию 0;
long занимает восемь байт, то есть 64 бита, 1 long = 64 бита, значение по умолчанию 0L;
Таким образом, размер байта, занимаемый целочисленным типом, равен long > int > short > byte.
- плавающая точка
Существует два типа данных с плавающей запятой: float и double.
float — тип с плавающей запятой одинарной точности, занимающий 4 бита, 1 float = 32 бита, значение по умолчанию — 0.0f;
double — тип с плавающей запятой двойной точности, занимающий 8 бит, 1 double = 64 бита, значение по умолчанию — 0.0d;
- тип персонажа
Тип символа — char, тип char — одиночный 16-битный символ Unicode, а минимальное значение —\u0000 (也就是 0 )
, максимальное значение\uffff (即为 65535)
, тип данных char может хранить любой символ, например char a = 'A'.
- логический
Логическое значение относится к логическому значению. Логическое значение имеет только два значения, истинное или ложное, что соответствует только 1 биту. Значение по умолчанию — ложное.
вышеx 位
Все ссылаются на занятость в памяти.
Базовая грамматика
- С учетом регистра: Java — это язык, чувствительный к регистру, например Hello и hello отличаются друг от друга, что на самом деле является строковым представлением Java.
- Имя класса: для всех классов первая буква должна быть заглавной, например.
MyFirstClass
- Имя пакета: имя пакета должно быть как можно меньше в нижнем регистре, например
my.first.package
- Имя метода: первая буква имени метода должна быть строчной, а каждая буква следующего слова должна быть прописной, например
myFirstMethod()
оператор
Операторы есть не только в Java, но и в других языках.Операторы — это некоторые специальные символы, которые в основном используются в математических функциях, некоторых типах операторов присваивания и логических сравнений.Давайте возьмем Java в качестве примера, чтобы взглянуть на операторы.
- оператор присваивания
Оператор присваивания использует оператор=
Это означает скопировать значение справа от знака = влево. Значение справа может быть любой константой, переменной или выражением, но значение слева должно быть явно определенной переменной. Напримерint a = 4
.
Но для объектов копируется не значение объекта, а ссылка на объект, поэтому, если вы говорите копирование объекта в другой объект, вы на самом деле копируетеПрисвоение ссылки на объект другому объекту.
- арифметические операторы
Арифметические операторы аналогичны числовым вычислениям в математике, в основном включая
Следует обратить внимание на арифметические операторы.优先级问题
, когда в выражении несколько операторов, приоритет операций определяет порядок вычислений.Самое простое правило — сначала умножить и разделить, а затем сложить и вычесть.()
Приоритет самый высокий, нет необходимости запоминать весь порядок приоритетов, вы можете использовать () напрямую, если вы не уверены.
- операторы инкремента и декремента
Это не объяснить на словах, объяснение лучше увидеть на примере напрямую
int a = 5;
b = ++a;
c = a++;
- оператор сравнения
Операторы сравнения используются для сравнения между переменными в программе, между переменными и аргументами и между другими типами информации.
Результатом оператора сравнения является логическое значение. Когда отношение, соответствующее оператору, установлено, результат операции истинен, в противном случае он ложен. Существует 6 операторов сравнения, которые обычно используются в условных операторах в качестве основы для суждения.
- Логические операторы
Есть три основных логических оператора: И, ИЛИ, НЕ
Ниже приведена таблица истинных/ложных символов, соответствующих логическим операторам.
- побитовые операторы
Побитовые операторы используются для работы с каждым из типов целочисленных примитивов.比特
Биты, то есть двоичные биты. Побитовые операторы выполняют булеву алгебру над соответствующими битами в двух аргументах и выдают результат.
Если обе стороны сравнения являются числами, сравнение становится побитовой операцией.
Побитовое И: операция И выполняется побитовое (И), результат равен 1, если оба операнда равны 1, иначе результат равен 0. Вам нужно сначала преобразовать обе стороны сравнения в двоичные файлы, а затем сравнить каждый бит
Побитовое ИЛИ: операция ИЛИ выполняется побитовым (ИЛИ), если один из двух битов равен 1, результат равен 1, в противном случае он равен 0.
Побитовое НЕ: побитовая операция исключающее ИЛИ (XOR), если бит равен 0, результат равен 1, если бит равен 1, результат равен 0.
Побитовое исключающее ИЛИ: побитовое отрицание (НЕ), если биты двух операндов одинаковы, результат равен 0, а если они разные, результат равен 1.
- оператор смены
Оператор сдвига используется для сдвига операнда в определенном направлении (влево или вправо) на указанное количество битов.
- Тернарный оператор
Тернарный оператор что-то вродеif...else...
Этот оператор, синтаксис:Условное выражение? Выражение 1: Выражение 2. Позиция перед знаком вопроса является условием решения.Результат решения является логическим.Когда оно истинно, вызывается выражение 1, а когда оно ложно, вызывается выражение 2.
Java выполняет поток управления
Поток управления в Java фактически такой же, как в C. В Java управление потоком включает в себя включениеесли-иначе, пока, делать-пока, для, вернуться, сломатьи выберите заявлениеswitch
. Ниже приводится анализ этого
Условные операторы
Условные операторы могут выполнять разные операторы на основе разных условий. Включая условные операторы if и операторы switch с несколькими ветвями.
если условное выражение
Оператор if может независимо судить о результате выражения, указывая результат выполнения выражения, например
int a = 10;
if(a > 10){
return true;
}
return false;
if...else условное выражение
Оператор if также может использоваться в сочетании с оператором else, как правило, какЕсли выполняется определенное условие, выполните один вид обработки, в противном случае выполните другой вид обработки..
int a = 10;
int b = 11;
if(a >= b){
System.out.println("a >= b");
}else{
System.out.println("a < b");
}
Выражение внутри () после if должно быть логического типа. Если true, то выполнить составной оператор после if, если false, выполнить составной оператор после else.
if...else if многоветвевой оператор
if...else в приведенном выше примере — это оценка одной ветви и двух ветвей.Если есть несколько условий оценки, вам нужно использоватьif...else if
int x = 40;
if(x > 60) {
System.out.println("x的值大于60");
} else if (x > 30) {
System.out.println("x的值大于30但小于60");
} else if (x > 0) {
System.out.println("x的值大于0但小于30");
} else {
System.out.println("x的值小于等于0");
}
оператор switch с несколькими ветвями
Более элегантный способ, чем оператор **if...else if **, заключается в использованииswitch
Оператор с несколькими ответвлениями, пример которого выглядит следующим образом.
switch (week) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("No Else");
break;
}
оператор цикла
Оператор цикла предназначен для многократного выполнения операции выражения при определенных условиях до тех пор, пока не будут выполнены требования оператора цикла. Используемые операторы цикла в основном включают **for, do...while(), а **,
оператор цикла
Оператор цикла while зацикливается, используя условие для управления повторным выполнением оператора. Формат оператора цикла while выглядит следующим образом.
while(布尔值){
表达式
}
Это означает, что когда (логическое значение) истинно, выполните следующее выражение, когда логическое значение ложно, завершите цикл, логическое значение на самом деле является выражением, например
int a = 10;
while(a > 5){
a--;
}
сделать... в то время как цикл
Единственная разница между циклом while и циклом do...while состоит в том, что оператор do...while выполняется хотя бы один раз, даже если в первый раз выражение ложно. В цикле while, если в первый раз условие ложно, то оператор в нем вообще не будет выполняться. На практике while используется более широко, чем do...while. Его общая форма выглядит следующим образом
int b = 10;
// do···while循环语句
do {
System.out.println("b == " + b);
b--;
} while(b == 1);
оператор цикла for
Цикл for — это форма цикла, которую мы часто используем, эта форма будет инициализирована перед первой итерацией. Он имеет форму
for(初始化; 布尔表达式; 步进){}
Булевы выражения проверяются перед каждой итерацией. Если полученный результат ложный, выполняется код после оператора for, и каждый раз, когда цикл завершается, выполняется следующий цикл в соответствии со значением шага.
оператор запятой
Одна вещь, которую нельзя здесь игнорировать, — это оператор запятой.Единственное, что использует оператор запятой в Java, — это оператор управления циклом for. В инициализирующей части выражения можно использовать серию операторов, разделенных запятыми; с помощью оператора запятая можно определить несколько переменных в операторе for, но они должны иметь один и тот же тип.
for(int i = 1;j = i + 10;i < 5;i++, j = j * 2){}
для каждого утверждения
В Java JDK 1.5 также представлен более лаконичный и удобный метод обхода массивов и коллекций, а именноfor-each
предложения, примеры следующие
int array[] = {7, 8, 9};
for (int arr : array) {
System.out.println(arr);
}
оператор перехода
В языке Java есть три оператора перехода:перерыв, продолжение и возврат
оператор перерыва
Мы видели оператор break в операторе switch. Это операция, используемая для завершения цикла. На самом деле, оператор break используется в операторах цикла for, while, do...while для принудительного выхода из текущего цикла, например:
for(int i = 0;i < 10;i++){
if(i == 5){
break;
}
}
продолжить заявление
continue также может быть помещен в оператор цикла, он имеет эффект, противоположный оператору break, его роль заключается в выполнении следующего цикла вместо выхода из текущего цикла, и в основном используется приведенный выше пример.
for(int i = 0;i < 10;i++){
System.out.printl(" i = " + i );
if(i == 5){
System.out.printl("continue ... ");
continue;
}
}
оператор возврата
Оператор return возвращает управление из метода и передает управление вызвавшему его оператору.
public void getName() {
return name;
}
объектно-ориентированный
Давайте обсудим идею объектно-ориентированного, идея объектно-ориентированного постепенно заменила идею процедурного --- процессно-ориентированного, Java - это объектно-ориентированный язык программирования высокого уровня, объектно-ориентированный язык имеет следующие характеристики
-
Объектно-ориентированный — это распространенное мнение, которое больше соответствует привычкам мышления людей;
-
Объектно-ориентированный подход может упростить сложную бизнес-логику и повысить возможность повторного использования кода;
-
Объектно-ориентированный имеет характеристики абстракции, инкапсуляции, наследования, полиморфизма и так далее.
К объектно-ориентированным языкам программирования в основном относятся: C++, Java, C# и др.
Следовательно, вы должны быть знакомы с объектно-ориентированным мышлением, чтобы писать программы на Java.
Класс также является объектом
Теперь давайте познакомимся с новой концепцией объектно-ориентированного --- класса, что такое класс, он эквивалентен абстракции ряда объектов, точно так же, как книга, класс эквивалентен обложке книги, большинство объектно-ориентированных языков используютclass
Чтобы определить класс, он сообщает вам, на что похожи объекты, определенные в нем, мы обычно используем следующее для определения класса
class ClassName {
// body;
}
Во фрагменте кода задействована новая концепция//
, о чем мы поговорим позже. Выше вы объявили класс class, теперь вы можете использовать new для создания этого объекта
ClassName classname = new ClassName();
В общем случае именование классов следует驼峰原则
, который определяется следующим образом
Camel-Case, также известный как Camel-Case, представляет собой набор правил (соглашений) именования, используемых при написании компьютерных программ. Как видно из его названия, CamelCase относится к использованию комбинации прописных и строчных букв для формирования имен переменных и функций. Чтобы программистам было проще общаться со своими коллегами, программисты применяют унифицированный и удобочитаемый метод именования.
создание объекта
В Яве,все является объектом. Я полагаю, что вы знакомы с этим предложением.Хотя все рассматривается как объект, то, чем вы манипулируете, является объектом.引用(reference)
. Здесь есть очень яркая аналогия: вы можете думать о ключах от машины и о машине как о группе.Ссылки на объекты и объектыКомбинация. Если вы хотите сесть за руль, вам сначала нужно вынуть ключ от машины и нажать кнопку разблокировки.При парковке вам нужно нажать кнопку блокировки, чтобы запереть машину. Ключ от машины эквивалентен ссылке, автомобиль является объектом, а ключ от машины используется для управления запиранием и отпиранием автомобиля. И даже без существования автомобиля ключ от автомобиля является независимой сущностью, т. е.у вас есть ссылка на объект, но вам не обязательно нужен объект, связанный с ним, это,
Car carKey;
Это создает ссылку, а не объект, но если вы попытаетесь использовать ссылку, будет возвращено исключение, сообщающее вам, что вам нужен объект для связи со ссылкой. Безопасной практикой является присвоение ему объекта при создании ссылки на объект.
Car carKey = new Car();
В Java, когда вы создаете ссылку, вы хотите, чтобы она была связана с новым объектом, обычно используяnew
оператора для достижения этой цели. новые средства, дай мне новый对象
, если вы не хотите свидания вслепую, просто создайте объект самостоятельно. Желаю счастья в следующей жизни.
свойства и методы
Одним из самых основных элементов класса является то, что он имеет свойства и методы.
Свойства, также известные как поля, являются важной частью класса, а свойства могут быть объектами любого типа или примитивными типами данных. Например, следующим образом
class A{
int a;
Apple apple;
}
Класс также должен включать методы, представляющиеспособ сделать что-то. Методы на самом деле являются функциями, но Java привыкла вызывать методы функций. Это название также отражает концепцию объектно-ориентированного.
К основным компонентам метода относятсяИмя метода, параметры, возвращаемое значение и тело метода, ниже приведен пример этого
public int getResult(){
// ...
return 1;
}
в,getResult
имя метода,()
Он представляет параметры, полученные методом,return
Указывает возвращаемое значение метода.Примечание: возвращаемое значение метода должно совпадать с возвращаемым значением метода.参数
Тип остается прежним. Существует специальный тип параметра ---void
Указывает, что метод не имеет возвращаемого значения.{}
Содержащийся сегмент кода называется телом метода.
Метод строительства
В Java есть специальный метод, называемый构造方法
, также известные как конструкторы, конструкторы и т. д. В Java этот конструктор обеспечивает инициализацию каждого объекта. Конструктор может быть вызван только один раз во время создания объекта, что обеспечивает инициализацию объекта. Метод построения особенный, он не имеет типа параметра и возвращаемого значения, его имя должно соответствовать имени класса, и может быть несколько методов построения, ниже приведен пример метода построения
class Apple {
int sum;
String color;
public Apple(){}
public Apple(int sum){}
public Apple(String color){}
public Apple(int sum,String color){}
}
Класс Apple определен выше. Вы обнаружите, что этот класс Apple не имеет типа параметра и возвращаемого значения и имеет несколько методов с тем же именем, что и Apple, и список параметров каждого Apple отличается. На самом деле это проявление полиморфизма. Мы поговорим об этом позже. После определения конструктора мы можем создать объект Apple.
class createApple {
public static void main(String[] args) {
Apple apple1 = new Apple();
Apple apple2 = new Apple(1);
Apple apple3 = new Apple("red");
Apple apple4 = new Apple(2,"color");
}
}
Как показано выше, мы определили четыре объекта Apple и вызвали четыре разных конструктора Apple, Среди них конструктор без каких-либо параметров называется конструктором по умолчанию, который
Apple apple1 = new Apple();
Если в классе не определен конструктор, JVM автоматически сгенерирует для вас конструктор, как показано ниже.
class Apple {
int sum;
String color;
}
class createApple {
public static void main(String[] args) {
Apple apple1 = new Apple();
}
}
Приведенный выше код не будет компилировать ошибки, поскольку объект Apple содержит конструктор по умолчанию.
Конструктор по умолчанию также известен как конструктор по умолчанию или конструктор без аргументов.
Здесь следует отметить одну вещь: даже если JVM по умолчанию добавит для вас конструктор без аргументов, если вы определите какой-либо конструктор вручную,JVM больше не будет предоставлять вам конструктор по умолчанию, вы должны указать его вручную, иначе произойдет ошибка компиляции.
Показанная ошибка заключается в том, что должен быть предоставлен конструктор Apple с параметром int, а конструктор по умолчанию без аргументов не разрешен.
перегрузка метода
Очень важной концепцией в Java является перегрузка методов, которая представляет собой другое представление имени класса. Мы упомянули конструктор выше, но конструктор также является своего рода перегрузкой. Другой - перегрузка метода
public class Apple {
int sum;
String color;
public Apple(){}
public Apple(int sum){}
public int getApple(int num){
return 1;
}
public String getApple(String color){
return "color";
}
}
Как показано выше, существует два метода перегрузки: один — это перегрузка конструктора Apple, а другой — перегрузка метода getApple.
Но это связано с проблемой: если их несколько с одинаковым именем, как Java узнает, какой метод вы вызываете? Только помни здесь одну вещь,Каждый перегруженный метод имеет уникальный список параметров.. К ним относятся тип, порядок, количество параметров и т. д. Удовлетворение одному фактору является необходимым условием для перегрузки.
Помните приведенное ниже состояние перегрузки
-
Имена методов должны быть одинаковыми.
-
Списки параметров должны быть разными (разное количество, разные типы, разный порядок типов параметров и т. д.).
-
Типы возвращаемых данных методов могут совпадать или не совпадать.
-
Простого наличия другого типа возвращаемого значения недостаточно, чтобы быть перегрузкой метода.
-
Перегрузка происходит во время компиляции, потому что компилятор может выбрать, какой метод использовать, исходя из типов аргументов.
переопределение метода
Переопределение и перегрузка методов имеют похожие названия, но это совершенно разные вещи. Описание переопределения метода верно子类和父类
между. И перегрузка относится к тому же классу. Например следующий код
class Fruit {
public void eat(){
System.out.printl('eat fruit');
}
}
class Apple extends Fruit{
@Override
public void eat(){
System.out.printl('eat apple');
}
}
Приведенный выше код описывает переписанный код.Вы можете видеть, что метод в подклассе Apple имеет то же имя, что и метод в родительском классе Fruit, поэтому мы можем вывести принцип перезаписи
- Переопределенный метод должен быть совместим с родительским классом, включаятип возвращаемого значения, имя метода, список параметровТо же самое.
- Можно использовать переопределенные методы
@Override
Аннотация для идентификации - Права доступа переопределенного метода в подклассе не могут быть ниже прав доступа метода в суперклассе.
инициализация
инициализация класса
Выше мы создали объект Car. Фактически, когда мы используем ключевое слово new для создания объекта, мы фактически вызываем конструктор объекта без параметров для инициализации, который представляет собой следующий код
class Car{
public Car(){}
}
Этот конструктор без параметров может быть скрыт и автоматически добавлен JVM. То есть конструктор обеспечивает инициализацию класса.
инициализация члена
Java постарается гарантировать, что каждая переменная будет инициализирована перед использованием, инициализация включает в себя два вида инициализации.
-
Один из них — инициализация поля, заданная компилятором по умолчанию, инициализация базовых типов данных.
Один из них — инициализация других типов объектов, String также является объектом, а начальное значение объекта равно
null
, который также включает классы-оболочки для примитивных типов. -
Одним из них является инициализация указанного значения, например
int a = 11
То есть указать, что значение инициализации a равно не 0, а 11. То же самое относится и к другим примитивным типам и типам объектов.
Инициализация конструктора
Конструкторы можно использовать для инициализации определенных методов и действий для определения начальных значений, таких как
public class Counter{
int i;
public Counter(){
i = 11;
}
}
С помощью конструктора значение i можно инициализировать равным 11.
порядок инициализации
Во-первых, давайте взглянем на последовательность инициализации, которую необходимо обсудить.
-
Статические свойства: свойства, определенные в начале статического
-
Блок статического метода: блок кода, заключенный в статический {}
-
Обычные свойства: свойства, которые не определены статически
-
Обычный блок метода: {} обернутый блок кода
-
Конструктор: метод с тем же именем класса
-
метод: обычный метод
public class LifeCycle {
// 静态属性
private static String staticField = getStaticField();
// 静态方法块
static {
System.out.println(staticField);
System.out.println("静态方法块初始化");
}
// 普通属性
private String field = getField();
// 普通方法块
{
System.out.println(field);
}
// 构造函数
public LifeCycle() {
System.out.println("构造函数初始化");
}
public static String getStaticField() {
String statiFiled = "Static Field Initial";
return statiFiled;
}
public static String getField() {
String filed = "Field Initial";
return filed;
}
// 主函数
public static void main(String[] argc) {
new LifeCycle();
}
}
Результат выполнения этого кода отражает порядок его инициализации.
Инициализация статического свойства Инициализация блока статического метода Обычная инициализация свойства Инициализация блока обычного метода инициализация конструктора
инициализация массива
Массив — это последовательность объектов или примитивных данных одного типа, инкапсулированных вместе с именем идентификатора. Доступ к массивам осуществляется с помощью оператора нижнего индекса в квадратных скобках.[]
для определения использования.
Общий массив определяется следующим образом
int[] a1;
//或者
int a1[];
Смысл обоих форматов одинаков.
- Назначьте каждый элемент напрямую: int array[4] = {1,2,3,4};
- Присвойте значение части, все следующие равны 0 : int array[4] = {1,2};
- Количество массивов определяется количеством параметров присваивания: int array[] = {1,2};
список переменных параметров
Непопулярное использование массивов в Java可变参数
, переменные параметры определяются следующим образом
public int add(int... numbers){
int sum = 0;
for(int num : numbers){
sum += num;
}
return sum;
}
Затем вы можете использовать следующие методы для выполнения вызовов с переменным числом аргументов.
add(); // 不传参数
add(1); // 传递一个参数
add(2,1); // 传递多个参数
add(new Integer[] {1, 3, 2}); // 传递数组
разрушение объектов
Хотя язык Java основан на C++, важной особенностью его и C/C++ является то, что нет необходимости вручную управлять уничтожением объектов. В известной книге "Глубокое понимание виртуальной машины Java" упоминается пункт
В Java нам больше не нужно вручную управлять уничтожением объектов, это делаетсяJava 虚拟机
управлял и уничтожал. Хотя нам не нужно управлять объектами вручную, вам нужно знать对象作用域
это понятие.
сфера действия объекта
Большинство языков имеют作用域(scope)
это понятие. Область определяет видимость и время жизни имен переменных, определенных в ней. В C, C++ и Java область обычно определяется{}
положение для принятия решения, например
{
int a = 11;
{
int b = 12;
}
}
переменная будет в двух{}
Область допустима, в то время как значение переменной b может быть только в ее собственном{}
действует в течение.
Хоть и есть сфера, писать не разрешено
{
int x = 11;
{
int x = 12;
}
}
Такой способ написания допустим в C/C++, но не разрешен в Java, потому что разработчики Java считают, что это приведет к путанице в программе.
###это и супер
оба this и super являются ключевыми словами в Java
Текущий объект, представленный this, который может вызывать методы, вызывать свойства и указывать на сам объект. Обычно в Java это используется тремя способами: указание на текущий объект
public class Apple {
int i = 0;
Apple eatApple(){
i++;
return this;
}
public static void main(String[] args) {
Apple apple = new Apple();
apple.eatApple().eatApple();
}
}
Этот код более тонкий. В чем тонкость? Мой метод eatApple() можно вызывать несколько раз, и вы можете продолжать вызывать его позже. Это удивительно, почему? На самом деле это то, что на работе, яeatApple
метод добавилreturn this
Возвращаемое значение , то есть любой объект, вызывающий метод eatApple, может вернуть сам объект.
это также может изменять свойства, чаще всего это используется в конструкторах, как показано ниже.
public class Apple {
private int num;
public Apple(int num){
this.num = num;
}
public static void main(String[] args) {
new Apple(10);
}
}
Метод main передает параметр со значением int, равным 10, который представляет количество яблок, и присваивает это число глобальной переменной num. Таким образом, значение num теперь равно 10.
это также можно использовать с конструкторами, чтобы действовать как глобальное ключевое слово
public class Apple {
private int num;
private String color;
public Apple(int num){
this(num,"红色");
}
public Apple(String color){
this(1,color);
}
public Apple(int num, String color) {
this.num = num;
this.color = color;
}
}
Вы обнаружите, что приведенный выше код не использует это, аthis(参数)
. Это эквивалентно вызову других конструкторов и передаче параметров. Обратите внимание: this() должен быть помещен в первую строку конструктора, иначе компиляция завершится ошибкой.
Если вы понимаете это как ссылку на себя, то super — это ссылка на суперкласс. Ключевое слово super такое же, как это, вы можете использоватьsuper.对象
для обращения к членам родительского класса следующим образом
public class Fruit {
int num;
String color;
public void eat(){
System.out.println("eat Fruit");
}
}
public class Apple extends Fruit{
@Override
public void eat() {
super.num = 10;
System.out.println("eat " + num + " Apple");
}
}
вы также можете использоватьsuper(参数)
для вызова конструктора родительского класса, здесь больше нет примеров.
Ниже приводится сводка сравнения ключевого слова this и ключевого слова super.
разрешения на управление доступом
разрешения на управление доступом封装
, это одна из трех основных характеристик объектно-ориентированного.Я часто игнорировал инкапсуляцию в процессе обучения раньше, думая, что это не модификатор доступа, почему это необходимое условие для трех характеристик? Позже я узнал,Если подчиненный, которому вы доверяете, скрывает от вас ошибку, вы даже не знаете об этом.
На самом деле, в основе разрешений управления доступом лежит одна точка: видимость только для необходимых классов.
В Java существует четыре типа разрешений доступа для членов, а именно:публичный, защищенный, по умолчанию, частный, их видимость следующая
наследовать
Наследство это всеOOP(Object Oriented Programming)
язык и язык Java являются неотъемлемыми частями. Пока мы создаем класс, он неявно наследуется отObject
Родительский класс, но не указан. Если вы явно указываете родительский класс, то вы наследуете от родительского класса, а ваш родительский класс наследуется от класса Object.
Унаследованное ключевое словоextends
, как показано на рисунке выше, если вы используете extends, чтобы показать, что указано наследование, то мы можем сказать, что Отец — это родительский класс, а Сын — подкласс, что выражается в коде следующим образом
class Father{}
class Son extends Father{}
Наследование обеих сторон имеет определенные общие характеристики
class Father{
public void feature(){
System.out.println("父亲的特征");
}
}
class Son extends Father {
}
Если Son не реализует собственный метод, то по умолчанию используется родительский класс.feature
метод. Если подкласс реализует свой собственный метод функций, это эквивалентно переопределению метода функций родительского класса, что также является переработкой, о которой мы упоминали выше.
полиморфизм
Полиморфизм означает, что одно и то же поведение имеет несколько различных проявлений. Это означает, что один и тот же метод экземпляра класса (объекта) имеет разные проявления в разных ситуациях. Инкапсуляция и наследование — основа полиморфизма, то есть полиморфизм — это всего лишь форма выражения.
Как добиться полиморфизма? Реализация полиморфизма имеет три необходимых и достаточных условия
- наследовать
- Переопределить метод родительского класса
- Ссылка родительского класса указывает на объект дочернего класса
Например следующий код
public class Fruit {
int num;
public void eat(){
System.out.println("eat Fruit");
}
}
public class Apple extends Fruit{
@Override
public void eat() {
super.num = 10;
System.out.println("eat " + num + " Apple");
}
public static void main(String[] args) {
Fruit fruit = new Apple();
fruit.eat();
}
}
ты можешь найтиmain
В методе есть очень волшебное место,Fruit fruit = new Apple()
, объект типа Fruit на самом деле указывает на ссылку объекта Apple, которая на самом деле является полиморфизмом -> ссылка родительского класса указывает на объект подкласса, потому что Apple наследует от Fruit и переписывает метод eat, поэтому он может отображать форму различные состояния.
комбинация
Композицию на самом деле понять не сложно, это поместить ссылки на объекты в новый класс. Композиция — это также способ улучшить возможность повторного использования классов. Если вы хотите, чтобы ваш класс имел более расширенную функциональность, вам нужно запомнить предложениеБольше композиции, меньше наследования.
public class SoccerPlayer {
private String name;
private Soccer soccer;
}
public class Soccer {
private String soccerName;
}
В коде SoccerPlayer ссылается на класс Soccer, а посредством ссылки на класс Soccer вызываются свойства и методы в футболе.
Между композицией и наследованием есть разница, и их основные отличия заключаются в следующем.
Споры о том, что лучше или хуже между наследованием и композицией, неубедительны, пока они играют в соответствии со своими сильными сторонами и преимуществами, в общем, композиция и наследование — это пара хороших братьев, которых можно использовать вместе.
играет роль
Помимо наследования и композиции, стоит изучить еще одну реляционную модель, которая называется代理
. Общее описание прокси состоит в том, что A хочет вызвать метод класса B, но A не вызывает его напрямую.A создаст прокси объекта B в своем собственном классе, а затем прокси вызовет метод B . Например следующий код
public class Destination {
public void todo(){
System.out.println("control...");
}
}
public class Device {
private String name;
private Destination destination;
private DeviceController deviceController;
public void control(Destination destination){
destination.todo();
}
}
public class DeviceController {
private Device name;
private Destination destination;
public void control(Destination destination){
destination.todo();
}
}
Преобразование вверх
Трансформация вверх представляет собой отношение между родительским классом и подклассом, на самом деле существуют не только переходы вверх между родительскими классами и подклассами, но и переходы вниз, и их области действия после преобразования различны.
-
向上转型
: преобразование объекта подкласса (маленький диапазон) в объект родительского класса (большой диапазон), это преобразование выполняется автоматически, принудительно не требуется. -
向下转型
: экземпляр объекта подкласса (маленький диапазон) через объект родительского класса (большой диапазон), это преобразование не выполняется автоматически и должно быть указано.
static
static — это ключевое слово в Java, оно означает静态的
, static можно использовать для изменения переменных-членов и методов, а static используется для вызова методов/переменных без создания объекта.
- Переменная-член, объявленная с помощью static, является статической переменной-членом, а также становится переменной класса. Переменные класса имеют тот же жизненный цикл, что и классы, и действуют на протяжении всего выполнения приложения.
static String name = "cxuan";
- Метод, дополненный static, называется статическим методом, и статический метод можно использовать напрямую.имя класса.имя методапозвонить. Поскольку к статическим методам можно обращаться напрямую, не полагаясь на какой-либо объект, для статических методов ключевое слово this отсутствует, а переменные экземпляра будут иметь это ключевое слово. Нестатические переменные-члены и нестатические методы класса не могут быть доступны в статических методах,
static void printMessage(){
System.out.println("cxuan is writing the article");
}
Помимо изменения свойств и методов, статические静态代码块
функция, которую можно использовать для операций инициализации класса. Это повышает производительность программы.
public class StaicBlock {
static{
System.out.println("I'm A static code block");
}
}
Поскольку блоки статического кода выполняются по мере загрузки классов, операции инициализации, которые необходимо выполнить только один раз, часто помещаются в блоки статического кода.
final
final означает окончательный, окончательный, он может изменять классы, свойства и методы.
- Когда final украшает класс, это указывает, что класс не может быть унаследован. Переменные-члены в конечных классах можно сделать окончательными по мере необходимости, но следует отметить, что все методы-члены в конечных классах неявно обозначаются как окончательные методы.
- При оформлении метода final это указывает на то, что метод не может быть переопределен ни одним подклассом, поэтому делайте метод final только в том случае, если вы хотите явно запретить переопределение метода в подклассах.
- Окончательная измененная переменная разделена на два случая: один — изменить базовый тип данных, указав, что значение типа данных не может быть изменено; другой — изменить ссылочный тип, указав, что он не может указывать на другой тип данных. объект после его инициализации.
Интерфейсы и абстрактные классы
интерфейс
Интерфейс эквивалентен внешнему соглашению и стандарту.Вот пример операционной системы.Зачем операционная система? Он обеспечит единый стандарт для программного обеспечения, чтобы скрыть разницу между сложностью программного обеспечения и простотой аппаратного обеспечения.
В языке Java интерфейс определяетсяinterface
Ключевое слово для обозначения, например, мы можем определить интерфейс следующим образом
public interface CxuanGoodJob {}
Например, мы определяем интерфейс CxuanGoodJob, а затем вы можете определить хорошие вещи, которые cxuan делает внутри него, например, статьи, написанные cxuan, хороши.
public interface CxuanGoodJob {
void writeWell();
}
Здесь подразумеваются некоторые особенности интерфейса:
-
interface
Интерфейс — это полностью абстрактный класс, который не предоставляет никакой реализации методов, а только определяет методы. - В интерфейсе можно использовать только два модификатора доступа, один
public
, который виден всему проекту;default
По умолчанию он имеет только пакетный доступ. - Интерфейс предоставляет только определение метода, интерфейс не имеет реализации, но интерфейс может быть реализован другими классами. То есть класс, реализующий интерфейс, должен обеспечивать реализацию метода, а реализация интерфейса использует
implements
ключевое слово, указывающее, что интерфейс может иметь несколько реализаций.
class CXuanWriteWell implements CxuanGoodJob{
@Override
public void writeWell() {
System.out.println("Cxuan write Java is vary well");
}
}
- Интерфейсы не могут быть созданы, поэтому в интерфейсах не может быть никаких конструкторов.Если вы определите конструктор, компиляция завершится ошибкой.
- Реализация интерфейса должна реализовывать все методы интерфейса, в противном случае он должен быть определен как
抽象类
, что мы собираемся сказать дальше
абстрактный класс
Абстрактный класс — это класс, чьи возможности абстракции слабее, чем у интерфейса.В Java абстрактные классы используютabstract
ключевое слово для указания. Если интерфейс описывается как вид собаки, то можно сказать, что абстрактный класс является породой с белой шерстью и маленьким телом, а класс реализации может быть конкретным классом, таким как шпиц, тедди и т. д. Вы можете определить абстрактный класс, как показано ниже
public interface Dog {
void FurColor();
}
abstract class WhiteDog implements Dog{
public void FurColor(){
System.out.println("Fur is white");
}
abstract void SmallBody();
}
В абстрактном классе он имеет следующие характеристики
-
Если у класса есть абстрактные методы, то класс должен быть абстрактным, то есть использовать ключевое слово
abstract
Измененный метод должен быть абстрактным методом, а класс с абстрактным методом должен быть абстрактным классом. Реализация методов класса имеет только специфичные для метода реализации. -
Абстрактные классы не обязательно имеют только абстрактные методы, абстрактные классы также могут иметь специфические методы, и вы можете выбирать, реализовывать эти методы или нет.
-
Ограничения в абстрактных классах не такие строгие, как интерфейсы, вы можете определить их в абстрактных классах.Конструкторы, абстрактные методы, обычные свойства, методы, статические свойства и статические методы
-
Абстрактные классы не могут быть созданы, как интерфейсы, экземпляры могут быть только созданы.
具体的类
аномальный
Исключения распространены в программах, и лучше всего искать ошибку на этапе компиляции, прежде чем вы попытаетесь запустить программу. Однако не все ошибки можно найти при компиляции, есть некоторыеNullPointerException
иClassNotFoundException
Исключения не обнаруживаются во время компиляции, эти исключения являются исключениями времени выполнения RuntimeException, и эти исключения часто обнаруживаются во время выполнения.
При написании программ на Java у нас часто возникают проблемы двух типов: java.lang.Exception и java.lang.Error, которые используются для указания того, что произошло исключение. концепции.
Распознать исключение
Exception
родыjava.lang
package, это интерфейс верхнего уровня, который наследуется отThrowable
Класс, класс исключения и его подклассы — все это составляющие условия Throwable, которые являются разумными ситуациями для появления программы.
Прежде чем знать Exception, необходимо понять, что такоеThrowable
.
Что можно бросать
Класс Throwable - это все错误(errors)
и异常(exceptions)
родительский класс. Только классы, которые унаследованы от Throwable или его подклассов, могут быть выброшены, и есть другой способ с Java.@throw
Аннотированные классы также могут бросать.
существуетСпецификация Java, определения непроверенных исключений и проверенных исключений следующие:
The unchecked exception classes are the run-time exception classes and the error classes.
The checked exception classes are all exception classes other than the unchecked exception classes. That is, the checked exception classes are
Throwable
and all its subclasses other thanRuntimeException
and its subclasses andError
and its subclasses.
То есть кромеRuntimeException
и его подклассы, иerror
и его подклассы, все остальные исключенияcheckedException
.
Затем, в соответствии с этой логической связью, мы можем классифицировать и анализировать Throwable и его подклассы.
Как видите, Throwable находится на верхнем уровне исключений и ошибок.Мы смотрим на класс Throwable и обнаруживаем, что у него много методов и свойств.Мы обсудим лишь некоторые из наиболее часто используемых.
// 返回抛出异常的详细信息
public string getMessage();
public string getLocalizedMessage();
//返回异常发生时的简要描述
public public String toString();
// 打印异常信息到标准输出流上
public void printStackTrace();
public void printStackTrace(PrintStream s);
public void printStackTrace(PrintWriter s)
// 记录栈帧的的当前状态
public synchronized Throwable fillInStackTrace();
Кроме того, поскольку родительский класс Throwable такжеObject
, поэтому часто используемые методы также наследуются от родительского класса.getClass()
иgetName()
метод.
Общее исключение
Вернемся к обсуждению Exception.Теперь вы знаете, что родительским классом Exception является Throwable, а у Exception есть два типа исключений:RuntimeException
; одинCheckedException
, оба исключения должны перейти к捕获
.
Ниже приведен список некоторых распространенных исключений в Java и их классификация. Этот интервьюер также может попросить вас назвать несколько распространенных исключений и классифицировать их.
RuntimeException
UncheckedException
Ключевые слова Java, связанные с исключением
Так как же обрабатываются эти исключения в Java? В Java есть несколько ключевых словкидает, бросает, старается, наконец, ловитдавайте обсудим отдельно
бросает и бросает
В Java исключение — это объект, который может быть создан программистом или приложением.throws
иthrow
Оператор для определения генерации исключений.
броски и бросок обычно парные, например.
static void cacheException() throws Exception{
throw new Exception();
}
Оператор throw используется в теле метода, чтобы указать, что создается исключение, которое обрабатывается оператором в теле метода. Оператор throws используется после объявления метода, чтобы указать, что исключение генерируется снова, которое обрабатывается вызывающей стороной метода.
throws в основном для того, чтобы объявить, что этот метод будет генерировать исключение этого типа, чтобы вызывающая сторона знала, что нужно перехватить это исключение. Throw — это действие по выбрасыванию исключения, поэтому оно создает экземпляр исключения.
попробуй, наконец, поймай
Эти три ключевых слова в основном имеют следующие комбинациипопробуй... поймай, попробуй... наконец, попробуй... поймай... наконец.
try...catch представляет захват исключения, которое может быть вызвано определенным фрагментом кода, следующим образом
static void cacheException() throws Exception{
try {
System.out.println("1");
}catch (Exception e){
e.printStackTrace();
}
}
try...finally означает, что независимо от того, как выполняется часть кода, код в finally будет выполнен.
static void cacheException() throws Exception{
for (int i = 0; i < 5; i++) {
System.out.println("enter: i=" + i);
try {
System.out.println("execute: i=" + i);
continue;
} finally {
System.out.println("leave: i=" + i);
}
}
}
То же самое верно и для try...catch...finally, что означает, что после перехвата исключения следует логика кода в finally.
Что такое ошибка
Ошибки — это ошибки, которые программа не может обработать и которые представляют собой более серьезные проблемы в работе приложения. Большинство ошибок не имеют ничего общего с действиями автора кода, а представляют собой проблему с JVM (виртуальная машина Java) во время выполнения кода. Эти ошибки невозможно проверить, потому что они находятся вне возможностей контроля и обработки приложения, и большинство из них являются условиями, которые не разрешены во время работы программы, напримерOutOfMemoryError
иStackOverflowError
Есть несколько ситуаций, в которых возникают исключения.Здесь нам нужно представить модель памяти Java JDK1.7.
Он состоит из двух частей,Область данных, совместно используемая всеми потоками, и область данных, изолированная от потокакомпозиция в приведенной выше модели памяти Java,только программный счетчикне случитсяOutOfMemoryError
Счетчик программ управляет ветвлениями, циклами, переходами, обработкой исключений и восстановлением потоков компьютерных инструкций, а счетчик программ является частным для каждого потока.
Что такое частный поток: это означает, что каждый поток не влияет друг на друга и независимо хранится в области памяти.
Если приложение выполняет метод Java, то этот счетчик записывает虚拟机字节码
адрес инструкции; если выполнениеNative
метод, значение счетчика равно空(Undefined)
.
В дополнение к счетчику программ, другие области:方法区(Method Area)
,虚拟机栈(VM Stack)
,本地方法栈(Native Method Stack)
и堆(Heap)
В обеих областях может возникнуть ошибка OutOfMemoryError.
-
Стек виртуальной машины: если глубина стека, запрошенная потоком, больше, чем глубина, разрешенная стеком виртуальной машины, она появится
StackOverflowError
Исключение; если динамическое расширение виртуальной машины не может применяться для достаточного количества памяти, оно появитсяOutOfMemoryError
. -
Стек собственных методов аналогичен стеку виртуальной машины.
-
Куча: куча Java может быть физически прерывистой и логически непрерывной, как и наше дисковое пространство.Если в куче нет памяти для завершения выделения экземпляра, и куча не может расширяться, будет выброшена ошибка OutOfMemoryError.
-
Область метода: если область метода не может удовлетворить требования к выделению памяти, будет выдано исключение OutOfMemoryError.
В Java вы можете думать об исключениях как о механизме, который может повысить надежность вашей программы, что позволяет вам обращать внимание на эти проблемы при написании кода, или вы можете сказать, что если вы пишете код, не обращая внимания на эти исключения, вы Вы не можете быть хардкорным программистом.
внутренний класс
Пока все, что мы знаем, это определение общего класса, то есть создание нового класса непосредственно в IDEA.
После того, как новое создание будет завершено, у вас будет определение файла класса.Эта операция слишком проста, и через долгое время она будет скучной.Большинству из нас, молодых людей, нужно обновить способ написания модно и высокомерно.Ну , поскольку вы упомянули об этом, используйте内部类
Ну, это полезный и раздражающий способ определения класса.Определение внутреннего класса очень простое:Вы можете поместить определение одного класса внутри другого класса, это внутренний класс.
Внутренние классы — очень полезная функция. Класс, определенный внутри класса, содержит ссылку на внешний класс, но невидим для других внешних классов.弗兰奇将军
Точно так же Фрэнки может общаться с генералом Фрэнки, но враг снаружи не может напрямую атаковать тело Фрэнки.
Теперь давайте поговорим о том, как создавать внутренние классы.
Создать внутренний класс
Определить внутренний класс очень просто, то есть определить класс непосредственно внутри внешнего класса, как показано в следующем коде.
public class OuterClass {
private String name ;
private int age;
class InnerClass{
public InnerClass(){
name = "cxuan";
age = 25;
}
}
}
В этом коде InnerClass является внутренним классом OuterClass. Другими словами, каждый внутренний класс может наследовать реализацию (интерфейса) независимо, поэтому независимо от того, унаследовал ли внешний класс реализацию (интерфейса), это не влияет на внутренний класс. Это также скрывает детали внутренней реализации.Внутренний класс имеет доступ к внешнему классу.
Внутренние классы могут быть определены не только внутри классов, но и внутри методов и областей видимости.局部内部类
, Кроме того, существуют анонимные внутренние классы, внутренние классы, которые могут реализовывать Java多重继承
. Вот как определяется внутренний класс
-
一个在方法中定义的类(局部内部类)
-
一个定义在作用域内的类,这个作用域在方法的内部(成员内部类)
-
一个实现了接口的匿名类(匿名内部类)
-
一个匿名类,它扩展了非默认构造器的类
-
一个匿名类,执行字段初始化操作
-
一个匿名类,它通过实例初始化实现构造
Поскольку каждый класс производит.class
файл, который содержит всю информацию о том, как создать объект этого типа, так как же представить информацию внутреннего класса? можно использовать$
представлять, напримерOuterClass$InnerClass.class.
собирать
Коллекции используются слишком много раз в нашей повседневной разработке, вы использовали их все тщательно, но как квалифицированный программист вы должны не только понимать их основное использование, но и понимать его исходный код; существование разумно, вам также нужно понимать, как он разработан и реализован, и вам также необходимо понимать процесс его создания.
Этот блог подробно расскажет о семейной системе и членах огромной коллекции фреймворка Collection, чтобы вы могли понять ее дизайн и реализацию.
Пришло время пожертвовать этим изображением бога
Первое, что нужно представить, это интерфейс списка бабушек и дедушек.Iterator
Итерируемый интерфейс
Реализация этого интерфейса позволяет объекту быть целью цикла for-each, т. е. улучшить цикл for, который является语法糖
.
List<Object> list = new ArrayList();
for (Object obj: list){}
В дополнение к объектам, реализующим этот интерфейс, массивы также могут быть пройдены с помощью цикла for-each следующим образом:
Object[] list = new Object[10];
for (Object obj: list){}
Другие методы обхода
До JDK 1.8Iterator
Существует только один метод итератора, который
Iterator<T> iterator();
Методы, реализующие этот интерфейс, могут создать упрощенный итератор для безопасного обхода элементов, удаления элементов и добавления элементов. Это включает в себяfail-fast
механизм.
Короче говоря, если вы можете создавать итераторы для добавления и удаления элементов, попробуйте использовать итераторы для добавления и удаления элементов.
Вы также можете использовать итераторы для обхода
for(Iterator it = coll.iterator(); it.hasNext(); ){
System.out.println(it.next());
}
интерфейс верхнего уровня
Коллекция — это интерфейс верхнего уровня, который в основном используется для определения соглашений о коллекциях.
Интерфейс List также является интерфейсом верхнего уровня, который наследует интерфейс Collection, а также является родительским классом элементов коллекции, таких как ArrayList и LinkedList.
Интерфейс Set находится на том же уровне, что и интерфейс List, и также наследует интерфейс Collection. Интерфейс Set предоставляет дополнительные возможности. Он предоставляет дополнительные критерии для методов add, equals, hashCode.
Queue — один из трех основных интерфейсов Collection наряду с интерфейсами List и Set. Очереди предназначены для поддержания порядка доступа к элементам перед обработкой. Очереди предоставляют дополнительные операции вставки, чтения и проверки в дополнение к основным операциям сбора.
Интерфейс SORTEDSET непосредственно унаследован в установленном интерфейсе и использует сопоставимое с естественным путем сортировки элементов или использовать компаратор, чтобы обеспечить индивидуальные правила сортировки для элементов при создании. Установленный итератор перейдет на коллекцию в соответствии с порядком восходящих элементов.
Map – это объект, поддерживающий хранение ключей и значений. Карта не может содержать повторяющиеся ключи, и каждый ключ соответствует не более чем одному значению. Этот интерфейс заменяет класс Dictionary, который является абстрактным классом, а не интерфейсом.
ArrayList
ArrayList реализует интерфейс List可扩容数组(动态数组)
, который внутренне реализован на основе массивов. Его конкретное определение выглядит следующим образом:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {...}
- ArrayList может реализовать все необязательные операции со списками, позволяя использовать все элементы, включая нулевые значения. ArrayList также предоставляет методы для внутреннего хранения списков, которые могут полностью заменить Vector, за одним исключением: ArrayList не является потокобезопасным контейнером.
- В ArrayList есть концепция емкости, емкость этого массива — это емкость списка, используемого для хранения элементов.
- ArrayList не является потокобезопасным контейнером. Если по крайней мере два потока из нескольких потоков изменят структуру ArrayList, это вызовет проблемы с потокобезопасностью. В качестве альтернативы можно использовать потокобезопасный список.
Collections.synchronizedList
.
List list = Collections.synchronizedList(new ArrayList(...))
- ArrayList имеет отказоустойчивый механизм быстрого отказа, который может обнаруживать отказ ArrayList. При изменении структуры коллекции в процессе итерации коллекции может произойти отказоустойчивость, то есть выброс
ConcurrentModificationException
аномальный.
Vector
Vector, как и ArrayList, реализован на основе массивов, за исключением того, что Vector является потокобезопасным контейнером, он просто и грубо блокирует каждый внутренний метод, чтобы избежать проблем с безопасностью, вызванных многопоточностью, но обычно эта синхронизация относительно большой, поэтому эффективность доступа к элементам намного ниже, чем у ArrayList.
Другой момент заключается в том, что длина массива после расширения ArrayList увеличится на 50%, а длина Vector после расширения удвоится.
Класс LinkedList
LinkedList — это двусвязный список, который позволяет хранить любой элемент (в том числе и null ). Его основные особенности заключаются в следующем:
- Все операции LinkedList могут быть выражены как двунаправленные.Операции, проиндексированные к связанному списку, будут проходиться от начала до конца, в зависимости от того, какое расстояние ближе всего к порядку обхода.
- Обратите внимание, что эта реализация также не является потокобезопасной.Если несколько потоков одновременно обращаются к связанному списку и хотя бы один из них изменяет структуру связанного списка, связанный список должен быть заблокирован извне. или использовать
List list = Collections.synchronizedList(new LinkedList(...))
Stack
стек - это то, что мы часто говорим后入先出(吃了吐)
контейнер. Он расширяет класс Vector и предоставляет обычные операции push и pop, а также метод просмотра вершины стека, метод empty для проверки того, пуст ли стек, и метод поиска для определения расстояния от вершины стека. стек.
При первом создании стека он не содержит элементов. Более полная и надежная работа стека LIFO обеспечивается интерфейсом Deque и его реализацией, и этот класс следует использовать в первую очередь.
Deque<Integer> stack = new ArrayDeque<Integer>()
HashSet
HashSet — это класс реализации интерфейса Set, поддерживаемый хэш-таблицей (фактически HashSet — это экземпляр HashMap). Это не гарантирует порядок итерации коллекции. Этот класс допускает нулевые элементы.
- Обратите внимание, что эта реализация не является потокобезопасной. Если несколько потоков одновременно обращаются к HashSet и хотя бы один поток изменяет набор, необходимо выполнить внешнюю блокировку. или использовать
Collections.synchronizedSet()
переопределение метода. - Эта реализация поддерживает отказоустойчивый механизм.
TreeSet
TreeSet — это реализация NavigableSet, основанная на TreeMap. Элементы сортируются с использованием их естественного порядка или компаратора, предоставленного во время создания, в зависимости от используемого конструктора.
- Эта реализация обеспечивает стоимость времени log(n) для основных операций добавления, удаления и содержания.
- Обратите внимание, что эта реализация не является потокобезопасной. Если несколько потоков одновременно обращаются к TreeSet и по крайней мере один поток изменяет набор, необходимо выполнить внешнюю блокировку. или использовать
SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...))
- Эта реализация содержит отказоустойчивый механизм.
Класс LinkedHashSet
LinkedHashSet наследует Set, сначала взгляните на систему наследования LinkedhashSet:
LinkedHashSet — это реализация хэш-таблицы и LinkedList интерфейса Set. Эта реализация отличается от HashSet тем, что поддерживает двусвязный список, который проходит через все записи. Этот связанный список определяет порядок, в котором элементы вставляются в коллекцию. Примечание. Если элемент вставлен повторно, порядок вставки не изменится.
- LinkedHashSet имеет два параметра, влияющих на его состав: начальную емкость и коэффициент загрузки. Они определяются точно так же, как HashSet. Но обратите внимание: выбор чрезмерно высокого значения начальной емкости обходится дешевле для LinkedHashSet, чем для HashSet, поскольку емкость не влияет на количество итераций LinkedHashSet.
- Обратите внимание, что LinkedHashSet также не является потокобезопасным.Если несколько потоков обращаются к LinkedHashSet одновременно, он должен быть заблокирован или с помощью
Collections.synchronizedSet
- Этот класс также поддерживает отказоустойчивый механизм.
PriorityQueue
PriorityQueue — это класс реализации AbstractQueue.Элементы приоритетной очереди сортируются в соответствии с естественной сортировкой или путем предоставления компаратора во время конструктора, который определяется конструктором. PriorityQueue не допускает пустых элементов.
- Голова очереди в некотором смысле является последним элементом в указанном порядке. Операции поиска в очереди опрашивают, удаляют, просматривают и получают доступ к элементу в начале очереди.
- Очередь с приоритетом не ограничена, но имеет внутреннюю емкость, которая контролирует размер массива, используемого для хранения элементов в очереди.
- Этот класс и итератор реализуют все необязательные методы интерфейсов Collection и Iterator. Этот итератор предоставляет
iterator()
Не гарантируется, что метод будет проходить элементы приоритетной очереди в любом конкретном порядке. Если вам нужен обход по порядку, рассмотрите возможность использованияArrays.sort(pq.toArray())
. - Обратите внимание, что эта реализация не является потокобезопасной, несколько потоков не должны одновременно обращаться к экземпляру PriorityQueue.Если поток изменяет очередь, используйте потокобезопасный класс.
PriorityBlockingQueue
.
HashMap
HashMap — это коллекция, которая использует принцип хеш-таблицы для хранения элементов и допускает пустые пары ключ-значение. HashMap не является потокобезопасным, что означает, что могут быть проблемы в многопоточной среде, в то время как Hashtable является потокобезопасным контейнером. HashMap также поддерживает отказоустойчивый механизм. Экземпляр HashMap имеет два параметра, влияющих на его производительность: начальную емкость и коэффициент загрузки. можно использоватьCollections.synchronizedMap(new HashMap(...))
для создания потокобезопасного HashMap.
Класс TreeMap
Красно-черное дерево на основе реализации NavigableMap. Эта карта хранится с естественной сортировкой по ключу или с пользовательской сортировкой с помощью компаратора.
-
TreeMap предоставляет служебные данные log(n) для методов containsKey, get, put и remove.
-
Обратите внимание, что эта реализация не является потокобезопасной. Если несколько потоков одновременно обращаются к TreeMap и по крайней мере один поток изменяет карту, необходимо выполнить внешнюю блокировку. Обычно это достигается путем синхронизации на каком-либо объекте, который естественным образом инкапсулирует коллекцию, или с помощью
SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...))
. -
Эта реализация содержит отказоустойчивый механизм.
Класс LinkedHashMap
LinkedHashMap — это хеш-таблица и реализация связанного списка интерфейса Map. Эта реализация отличается от HashMap тем, что поддерживает двусвязный список во всех своих записях. Этот связанный список определяет порядок обхода, обычно порядок вставки в карту.
-
Он предоставляет специальный конструктор LinkedHashMap(int,float,boolean) для создания LinkedHashMap, порядок обхода которого совпадает с порядком последнего посещения.
-
Метод removeEldestEntry(Map.Entry) можно переопределить, чтобы применить стратегию удаления карт с истекшим сроком действия при добавлении новой карты на карту.
-
Этот класс предоставляет все необязательные операции с картами и допускает нулевые элементы. Из-за дополнительных накладных расходов на поддержание связанного списка производительность может быть ниже, чем у HashMap, за одним исключением: обход представлений-коллекций в LinkedHashMap должен быть пропорционален map.size, независимо от его емкости. Итерация по HashMap кажется более дорогой, поскольку она также требует времени, пропорционального ее емкости.
-
LinkedHashMap имеет два фактора, влияющих на его состав: начальная емкость и коэффициент загрузки.
-
Обратите внимание, что эта реализация не является потокобезопасной. Если несколько потоков одновременно обращаются к LinkedHashMap и хотя бы один поток изменяет карту, необходимо выполнить внешнюю блокировку. Обычно это достигается путем синхронизации с некоторым объектом, который естественным образом инкапсулирует коллекцию.
Map m = Collections.synchronizedMap(new LinkedHashMap(...))
. -
Эта реализация содержит отказоустойчивый механизм.
Класс хэш-таблицы
Класс Hashtable реализует хэш-таблицу, способную сопоставлять ключи со значениями. В качестве ключа или значения можно использовать любой ненулевой объект.
- Этот класс реализации поддерживает отказоустойчивый механизм
- В отличие от новой реализации коллекции, Hashtable является потокобезопасным. Если потокобезопасные контейнеры не требуются, рекомендуется использовать HashMap.Если требуется многопоточность и высокий параллелизм, рекомендуется использовать
ConcurrentHashMap
.
Класс IdentityHashMap
IdentityHashMap — относительно нишевая реализация карты.
- Этот класс не является общей реализацией Map! Хотя этот класс реализует интерфейс Map, он намеренно нарушает контракт Map, который требует использования метода equals при сравнении объектов, и этот класс полезен только в редких случаях, когда требуется семантика равенства ссылок.
- Как и HashMap, IdentityHashMap также неупорядочен, и этот класс не является потокобезопасным.Если вы хотите сделать его потокобезопасным, вы можете вызвать
Collections.synchronizedMap(new IdentityHashMap(...))
метод достижения. - Поддержка отказоустойчивого механизма
Класс WeakHashMap
Класс WeakHashMap — это базовая реализация Map на основе хэш-таблицы со слабыми ключами. Записи в WeakHashMap также автоматически удаляются, когда они больше не используются. Точнее, наличие карты для данного ключа не предотвратит отбрасывание ключа сборщиком мусора.
- Судя по интерфейсу карты, это слабое ключевое соединение, и ключи в WeakHashMap будут автоматически переработаны.
- Поддерживаются нулевые значения и нулевые ключи.
- быстродействующий механизм
- Дубликаты не допускаются
- WeakHashMap часто используется в качестве кэша
Класс коллекций
Коллекции не относятся к содержимому дерева наследования фреймворка Java, они относятся к отдельной ветке, Коллекции — это класс-оболочка, его роль заключается в предоставлении некоторой функциональной реализации для фреймворка коллекций, этот класс включает только операции статического метода или возвращает коллекции.
Синхронизированная упаковка
Оболочки синхронизации добавляют автоматическую синхронизацию (безопасность потоков) к произвольным коллекциям. Каждый из шести базовых интерфейсов коллекций (Collection, Set, List, Map, SortedSet и SortedMap) имеет статический фабричный метод.
public static Collection synchronizedCollection(Collection c);
public static Set synchronizedSet(Set s);
public static List synchronizedList(List list);
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m);
public static SortedSet synchronizedSortedSet(SortedSet s);
public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m);
немодифицируемая упаковка
Немодифицируемая оболочка перехватывает операции, изменяющие коллекцию, и выбрасываетUnsupportedOperationException
, в основном используется в следующих двух сценариях:
- Сделайте коллекцию неизменной после ее создания. В этом случае лучше не получать ссылку на возвращаемую коллекцию, что хорошо для обеспечения неизменности
- Разрешить доступ только для чтения к вашим структурам данных для определенных клиентов. Вы сохраняете ссылку на возвращаемую коллекцию, но распространяете ссылку на оболочку. Таким образом, клиенты могут просматривать, но не изменять, сохраняя при этом полный доступ.
Эти методы:
public static Collection unmodifiableCollection(Collection<? extends T> c);
public static Set unmodifiableSet(Set<? extends T> s);
public static List unmodifiableList(List<? extends T> list);
public static <K,V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m);
public static SortedSet unmodifiableSortedSet(SortedSet<? extends T> s);
public static <K,V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, ? extends V> m);
Поточно-безопасные коллекции
Параллельный пакет Java1.5(java.util.concurrent)
Предоставляет потокобезопасные коллекции, которые позволяют модифицировать во время обхода, за счет проектирования итератора, обеспечивающего отказоустойчивость и вызывающего исключение ConcurrentModificationException. Некоторые классы реализацииCopyOnWriteArrayList
,ConcurrentHashMap
,CopyOnWriteArraySet
Алгоритм коллекций
Этот класс содержит методы для алгоритмов набора фреймворков, таких как бинарный поиск, сортировка, перестановка, реверсирование и т. д.
Карта функций класса реализации коллекции
На следующем рисунке обобщены карты функций основных классов реализации некоторых фреймворков коллекций, чтобы вы могли четко увидеть различия между каждым классом реализации.
Существует также статья о сильных ссылках, слабых ссылках и виртуальных ссылках, см.
Tickets.WeChat.QQ.com/Yes/ZF lb PN2TB…
общий
В Jdk1.5 предлагается новая концепция, то есть дженерики, так что же такое дженерики?
Обобщения на самом деле представляют собой параметризованную коллекцию, которая ограничивает типы, которые вы можете добавить в коллекцию. Универсальные типы по сути являются параметризованным типом. Полиморфизм также можно рассматривать как механизм дженериков. Класс наследует родительский класс, тогда соответствующий подкласс можно найти через его родительский класс, но конкретный класс, который вы ищете, не может быть найден через другие классы. Обобщения предназначены для максимально широкой выразительности объектов или методов.
Давайте посмотрим на пример, чтобы проиллюстрировать использование без дженериков.
List arrayList = new ArrayList();
arrayList.add("cxuan");
arrayList.add(100);
for(int i = 0; i< arrayList.size();i++){
String item = (String)arrayList.get(i);
System.out.println("test === ", item);
}
Эта программа не работает должным образом, поскольку тип Integer нельзя напрямую привести к типу String.
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Если мы перепишем его с помощью дженериков, пример кода будет следующим
List<String> arrayList = new ArrayList<String>();
arrayList.add(100);
Этот код сообщит об ошибке во время компиляции, и компилятор сможет помочь нам найти подобные проблемы на этапе компиляции.
Использование дженериков
Есть много способов использовать дженерики, давайте обсудим их вместе.
Представление классов с помощью дженериков
Обобщения могут быть добавлены к классу для представления типа класса.
//此处 T 可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
public class GenericDemo<T>{
//value 这个成员变量的类型为T,T的类型由外部指定
private T value;
public GenericDemo(T value) {
this.value = value;
}
public T getValue(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
return value;
}
public void setValue(T value){
this.value = value
}
}
Представление интерфейса с помощью дженериков
Определение и использование универсального интерфейса и универсального класса в основном одинаковы.
//定义一个泛型接口
public interface Generator<T> {
public T next();
}
Универсальные интерфейсы обычно используются в生成器(generator)
В , генератор эквивалентен фабрике объектов, классу, специально используемому для создания объектов.
общий метод
Вы можете использовать дженерики для представления методов
public class GenericMethods {
public <T> void f(T x){
System.out.println(x.getClass().getName());
}
}
Общие подстановочные знаки
Список является универсальным классом. Чтобы представить родительский класс различных универсальных списков, можно использовать подстановочные знаки типов, а также можно использовать подстановочные знаки типов.问号(?)
означает, что его тип элемента может соответствовать любому типу. Например
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("cxuan");
age.add(18);
number.add(314);
generic(name);
generic(age);
generic(number);
}
public static void generic(List<?> data) {
System.out.println("Test cxuan :" + data.get(0));
}
Подстановочный знак Нижнего мира: Этот подстановочный знак означает все подтипы ClassType. Это означает, что любой тип является подклассом типа ClassType.
подстановочный знак верхней границы: Этот подстановочный знак означает все супертипы ClassType. Это означает, что суперкласс любого типа является ClassType.
отражение
Отражение — очень важная и продвинутая функция в Java.В основном, серия фреймворков, таких как Spring, написана на основе идеи отражения. Давайте сначала разберемся, что такое отражение.
Механизм отражения Java заключается в том, что во время выполнения программы для любого класса она может знать все его свойства и методы, для любого объекта она может знать любые свойства и методы, которые ее вызывают.Это динамическое получение информации и динамический вызов Функция объектного метода называется механизмом отражения языка java.(из энциклопедии Baidu)
Механизм отражения Java в основном предоставляет следующие функции.
- Определить класс, к которому принадлежит любой объект во время выполнения
- Создание объекта любого класса во время выполнения
- Определить все переменные-члены и методы любого класса во время выполнения
- Вызов метода для любого объекта во время выполнения
Глядя на это с этой точки зрения, отражение похоже на роль, которая контролирует общую ситуацию.Независимо от того, как работает ваша программа, я могу знать, какие свойства и методы есть у вашего класса, и кто называет ваш объект, ммм, очень крутым.
В Java используйтеJava.lang.reflect
В пакете реализован механизм отражения. Классы, разработанные Java.lang.reflect, следующие:
Ниже приведен простой класс отражения
public class Person {
public String name;// 姓名
public int age;// 年龄
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String showInfo() {
return "name=" + name + ", age=" + age;
}
}
public class Student extends Person implements Study {
public String className;// 班级
private String address;// 住址
public Student() {
super();
}
public Student(String name, int age, String className, String address) {
super(name, age);
this.className = className;
this.address = address;
}
public Student(String className) {
this.className = className;
}
public String toString() {
return "姓名:" + name + ",年龄:" + age + ",班级:" + className + ",住址:"
+ address;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class TestRelect {
public static void main(String[] args) {
Class student = null;
try {
student = Class.forName("com.cxuan.reflection.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 获取对象的所有公有属性。
Field[] fields = student.getFields();
for (Field f : fields) {
System.out.println(f);
}
System.out.println("---------------------");
// 获取对象所有属性,但不包含继承的。
Field[] declaredFields = student.getDeclaredFields();
for (Field df : declaredFields) {
System.out.println(df);
}
// 获取对象的所有公共方法
Method[] methods = student.getMethods();
for (Method m : methods) {
System.out.println(m);
}
System.out.println("---------------------");
// 获取对象所有方法,但不包含继承的
Method[] declaredMethods = student.getDeclaredMethods();
for (Method dm : declaredMethods) {
System.out.println(dm);
}
// 获取对象所有的公共构造方法
Constructor[] constructors = student.getConstructors();
for (Constructor c : constructors) {
System.out.println(c);
}
System.out.println("---------------------");
// 获取对象所有的构造方法
Constructor[] declaredConstructors = student.getDeclaredConstructors();
for (Constructor dc : declaredConstructors) {
System.out.println(dc);
}
Class c = Class.forName("com.cxuan.reflection.Student");
Student stu1 = (Student) c.newInstance();
// 第一种方法,实例化默认构造方法,调用set赋值
stu1.setAddress("河北石家庄");
System.out.println(stu1);
// 第二种方法 取得全部的构造函数 使用构造函数赋值
Constructor<Student> constructor = c.getConstructor(String.class,
int.class, String.class, String.class);
Student student2 = (Student) constructor.newInstance("cxuan", 24, "六班", "石家庄");
System.out.println(student2);
/**
* 獲取方法并执行方法
*/
Method show = c.getMethod("showInfo");//获取showInfo()方法
Object object = show.invoke(stu2);//调用showInfo()方法
}
}
Некоторые из них используются чаще, некоторые из которых я никогда не видел, как их использовать.Ниже приводится классификация.
Классы, связанные с отражением Java, в основном
класс класс
В Java каждый раз, когда вы определяете объект класса java, будет генерироваться объект класса. То есть, когда мы пишем класс после завершения компиляции, в сгенерированном.class
В файле будет сгенерирован объект класса, который используется для представления информации о типе этого класса. В классе нет общедоступного конструктора, что означает, что объекты класса не могут быть созданы. Давайте кратко рассмотрим, какие методы включены в класс Class.
toString()
public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}
Метод toString() может преобразовать объект в строку. toString() сначала определит, является ли тип Class типом интерфейса, то есть обычные классы и интерфейсы могут быть представлены объектом Class, а затем определит, является ли он типом класса. базовый тип данных. Здесь оцениваются базовые типы данных и классы-оболочки, а такжеvoid
тип.
Все типы следующие
- java.lang.Boolean: логические данные, представляющие тип упаковки.
- java.lang.Character: класс-оболочка, представляющий тип данных char.
- java.lang.Byte: класс-оболочка, представляющий тип данных byte.
- java.lang.Short: класс-оболочка, представляющий короткий тип данных.
- java.lang.Integer: класс-оболочка, представляющий тип данных int.
- java.lang.Long: класс-оболочка, представляющий тип данных long.
- java.lang.Float: класс-оболочка, представляющий тип данных float.
- Java.lang.double: класс упаковки, представляющий тип данных Double.
- java.lang.Void: класс-оболочка, представляющий тип данных void.
ПослеgetName()
метод, который возвращает полное имя класса.
- Если это ссылочный тип, например String.class.getName() ->
java.lang.String
- Если это базовый тип данных, byte.class.getName() ->
byte
- Если это тип массива, new Object[3]).getClass().getName() ->
[Ljava.lang.Object
toGenericString()
Этот метод возвращает полное имя класса, включая модификаторы класса и сведения о параметрах типа.
forName()
Получите ссылку на объект класса по имени класса, этот метод инициализирует объект класса.
НапримерClass t = Class.forName("java.lang.Thread")
может инициализировать объект потока Thread
В Java есть три способа получить экземпляр класса.
- Class.forName(java.lang.Thread)
- Thread.class
- thread.getClass()
newInstance()
Создает экземпляр класса, который представляет объект этого класса. Приведенный выше метод forName() инициализирует класс, а метод newInstance создает экземпляр класса.
getClassLoader()
Получите объект загрузчика классов.
getTypeParameters()
Получите информацию о типе параметра объекта в порядке объявления.
getPackage()
пакет, который возвращает класс
getInterfaces()
Получить класс или интерфейс, реализованный текущим классом, их может быть несколько, поэтому возвращаемым является массив классов.
Cast
Преобразование объекта в объект, представляющий класс или интерфейс
asSubclass(Class clazz)
Преобразует объект переданного класса в объект, представляющий его подкласс
getClasses()
Возвращает массив, содержащий объекты всех общедоступных и интерфейсных классов в классе
getDeclaredClasses()
Возвращает массив, содержащий объекты всех классов и классов интерфейса в этом классе
getSimpleName()
получить имя класса
getFields()
Получить все объекты публичной собственности
getField(String name)
Получить объект публичной собственности
getDeclaredField(String name)
получить объект недвижимости
getDeclaredFields()
получить все объекты недвижимости
getAnnotation(Class annotationClass)
Возвращает общедоступный объект аннотации в этом классе, соответствующий типу параметра.
getAnnotations()
Возвращает все общедоступные объекты аннотаций этого класса.
getDeclaredAnnotation(Class annotationClass)
Возвращает все объекты аннотации в этом классе, которые соответствуют типу параметра
getDeclaredAnnotations()
Возвращает все объекты аннотации этого класса
getConstructor(Class...<?> parameterTypes)
Получить общедоступный конструктор в этом классе, который соответствует типу параметра
getConstructors()
Получить все общедоступные конструкторы этого класса
getDeclaredConstructor(Class...<?> parameterTypes)
Получите конструктор в этом классе, который соответствует типу параметра
getDeclaredConstructors()
Получить все конструкторы этого класса
getMethod(String name, Class...<?> parameterTypes)
Получить публичный метод этого класса
getMethods()
Получить все общедоступные методы этого класса
getDeclaredMethod(String name, Class...<?> parameterTypes)
получить метод этого класса
getDeclaredMethods()
Получить все методы этого класса
Класс поля
Класс Field предоставляет информацию об отдельных полях класса или интерфейса, а также динамический доступ к отдельным полям.
Конкретные методы здесь описываться не будут, читатели, которым это интересно, могут обратиться к официальному API.
Вот лишь несколько часто используемых методов
equals(Object obj)
Возвращает true, если свойство равно obj
get(Object obj)
Получить соответствующее значение свойства в obj
set(Object obj, Object value)
Установите соответствующее значение свойства в obj
Класс метода
invoke(Object obj, Object... args)
Передайте объект объекта и параметры для вызова метода, соответствующего объекту
Класс ClassLoader
При отражении другим очень важным классом является класс ClassLoader.Загрузчик классов используется для类(class)
загружен вJVM
из. ClassLoader использует родительскую модель делегирования для поиска загруженных классов, которая также является родительской моделью делегирования. Схема наследования классов ClassLoader выглядит следующим образом.
перечислить
Перечисление может быть функцией, которую мы используем реже.enum
ключевое слово, чтобы указать, что перечисления на самом деле очень полезная функция, и вы можете думать о них как о классах с определенными свойствами. Enum — это не только Java, C и C++ также имеют концепцию перечисления. Ниже приведен пример перечисления.
public enum Family {
FATHER,
MOTHER,
SON,
Daughter;
}
Выше мы создалиFamily
Класс перечисления, который имеет 4 значения, представлен прописными буквами, поскольку типы перечисления являются константами. Затем создается перечисление, как на него сослаться?
public class EnumUse {
public static void main(String[] args) {
Family s = Family.FATHER;
}
}
свойства перечисления
Класс перечисления enum интересен, когда вы создаете перечисление, компилятор автоматически добавит его в ваше перечисление.toString()
метод, который позволяет удобно отображать конкретное имя экземпляра перечисления. В дополнение к методу toString() компилятор добавляетordinal()
метод, который используется для указания порядка объявления констант перечисления, иvalues()
Метод отображает стоимость заказа.
public static void main(String[] args) {
for(Family family : Family.values()){
System.out.println(family + ", ordinal" + family.ordinal());
}
}
enum может статически импортировать пакеты, а статически импортировать пакеты можно без ввода枚举类名.常量
, вы можете использовать константы напрямую, магия?Используйте ennum иstatic
Ключевое слово может делать статический пакет импорта
Приведенный выше код импортирует все константы в Family, и вы также можете указать константы по отдельности.
Перечисления такие же, как обычные классы
Перечисления аналогичны обычным классам, за исключением того, что их можно легко и быстро определить в перечислениях.常量
, которые мы используем в нашей повседневной разработкеpublic static final xxx
На самом деле его можно определить перечислением. Атрибуты и методы также могут быть определены в перечислении, не думайте об этом как о разнородном, это то же самое, что и тысячи классов.
public enum OrdinalEnum {
WEST("live in west"),
EAST("live in east"),
SOUTH("live in south"),
NORTH("live in north");
String description;
OrdinalEnum(String description){
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static void main(String[] args) {
for(OrdinalEnum ordinalEnum : OrdinalEnum.values()){
System.out.println(ordinalEnum.getDescription());
}
}
}
Как правило, switch можно использовать вместе с enum для создания небольшой машины перехода между состояниями.
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
Стал ли код вдруг более элегантным и аккуратным?
перечислять тайны
В Java все является объектом.Хотя enum является ключевым словом, оно неявно наследуется отEnum
своего рода. Давайте взглянем на класс Enum, который находится вjava.lang
Под пакетом на него можно автоматически сослаться.
Этот класс имеет меньше свойств и методов. Вы заметите, что нашего метода значений нет в этом классе. Я только что сказал раньше,values()
Методы — это статические методы, добавляемые компилятором при использовании перечислений.Вы можете использовать отражение для проверки.
Кроме того, enum также пересекается с классом Class, и в классе Class есть три метода для Enum.
Первые два метода используются для получения констант перечисления,isEnum
Используется, чтобы определить, является ли он типом перечисления.
перечисляемый класс
В дополнение к Enum вам также необходимо знать два класса инструментов для перечисления, один из которыхEnumSet
,одинEnumMap
EnumSet и EnumMap
EnumSet был представлен в JDK1.5. Дизайн EnumSet полностью учитывает фактор скорости. Использование EnumSet можно использовать в качестве альтернативы Enum, поскольку он более эффективен.
EnumMap — это особый тип Map, который требует, чтобы значение ключа было из перечисления. Поскольку EnumMap также работает быстро, мы можем использовать EnumMap в качестве ключа для быстрого поиска.
В целом, использование перечислений не очень сложно, это тоже небольшая часть функциональности в Java, но иногда она может сделать ваш код элегантным и чистым из-за этой маленькой хитрости.
I/O
Создать хорошую программу ввода-вывода очень сложно. Разработчики JDK пишут тонны классов только для того, чтобы иметь возможность создать хороший набор инструментов, а написание набора инструментов ввода-вывода требует много работы.
Класс IO определенно предназначен для решения операций, связанных с вводом-выводом.Наиболее распространенными операциями чтения и записи ввода-вывода являются сеть, диск и т. д. В Java операция с файлом является типичной операцией ввода-вывода. Далее мы классифицируем ввод-вывод.
ответ на общедоступный номер
IO
Получить ментальную карту
Ввод/вывод также можно различать в зависимости от объекта операции: в основном делится на
Кроме того, в вводе-выводе есть и другие более важные классы.
Класс файла
Класс File — это класс, который работает с файлами и папками в файловой системе.Он может работать с файлами и папками посредством объектно-ориентированного мышления.Разве это не удивительно?
Операция создания файла выглядит следующим образом, в основном с участиемСоздание файлов, удаление файлов, получение файловых дескрипторов и т. д.
class FileDemo{
public static void main(String[] args) {
File file = new File("D:\\file.txt");
try{
f.createNewFile(); // 创建一个文件
// File类的两个常量
//路径分隔符(与系统有关的)<windows里面是 ; linux里面是 : >
System.out.println(File.pathSeparator); // ;
//与系统有关的路径名称分隔符<windows里面是 \ linux里面是/ >
System.out.println(File.separator); // \
// 删除文件
/*
File file = new File(fileName);
if(f.exists()){
f.delete();
}else{
System.out.println("文件不存在");
}
*/
}catch (Exception e) {
e.printStackTrace();
}
}
}
Вы также можете работать с папками
class FileDemo{
public static void main(String[] args) {
String fileName = "D:"+ File.separator + "filepackage";
File file = new File(fileName);
f.mkdir();
// 列出所有文件
/*
String[] str = file.list();
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
*/
// 使用 file.listFiles(); 列出所有文件,包括隐藏文件
// 使用 file.isDirectory() 判断指定路径是否是目录
}
}
Выше приведены два простых примера, на самом деле есть еще какие-то операции над файлами, которые не используются. Например, чтобы создать файл, вы можете использовать три метода создания
File(String directoryPath);
File(String directoryPath, String filename);
File(File dirObj, String filename);
directoryPath — это путь к файлу, filename — это имя файла, а dirObj — это объект File. Например
File file = new File("D:\\java\\file1.txt"); //双\\是转义
System.out.println(file);
File file2 = new File("D:\\java","file2.txt");//父路径、子路径--可以适用于多个文件的!
System.out.println(file2);
File parent = new File("D:\\java");
File file3 = new File(parent,"file3.txt");//File类的父路径、子路径
System.out.println(file3);
Теперь подведем итоги класса File
Основные классы ввода-вывода и связанные с ними методы
Хотя существует множество классов .IO, самыми основными из них являются четыре абстрактных класса.InputStream, OutputStream, Reader, Writer. Самый основной метод этоread()
иwrite()
метод, другие потоки являются подклассами вышеупомянутых четырех типов потоков, и методы также являются производными от этих двух типов методов. И большая часть исходного кода IOnative
Подписанный, то есть исходный код написан на C/C++. Здесь мы сначала рассмотрим эти потоковые классы и их методы.
InputStream
InputStream — это абстрактный класс, определяющий схему ввода байтов потока Java. Все методы этого класса вызывают исключение IOException при возникновении ошибки. Его основной метод определяется следующим образом
OutputStream
OutputStream — это абстрактный класс, определяющий схему потокового вывода байтов. Все методы этого класса возвращают пустое значение и вызывают исключение IOException в случае ошибки. Его основной метод определяется следующим образом
Читательский класс
Reader — это абстрактный класс для режима потокового ввода символов, определенного в Java. Метод в классе выдает ошибкуIOException
аномальный.
Класс писателя
Writer — это абстрактный класс, определяющий потоковый вывод символов. Все методы этого класса возвращают пустое значение и вызывают исключение IOException при возникновении ошибки.
InputStream и его подклассы
Входной поток файла FileInputStream: класс FileInputStream создает класс InputStream, который может считывать байты из файла.
Входной поток массива байтов ByteArrayInputStream: использовать буфер в памяти как InputStream
Конвейерный входной поток PipedInputStream: Реализует концепцию трубы, в основном используемую в потоках.
Последовательный входной поток SequenceInputStream: объединить несколько InputStreams в один InputStream.
FilterOutputStream фильтрует входной поток: оболочка для других входных потоков.
ObjectInputStream десериализует входной поток: восстановить исходные данные, сериализованные с помощью ObjectOutputStream, как объект и прочитать объект в потоке.
DataInputStream: потоки ввода данных позволяют приложениям считывать основные типы данных Java из основного потока ввода машинно-независимым способом.
PushbackInputStream отталкивает входной поток: новое использование буферизации заключается в реализации推回 (pushback)
. Pushback используется во входном потоке, чтобы байты могли быть прочитаны, а затем возвращены в поток.
OutputStream и его подклассы
Выходной поток файла FileOutputStream: этот класс реализует поток вывода, данные которого записываются в файл.
Выходной поток массива байтов ByteArrayOutputStream: этот класс реализует поток вывода, данные которого записываются в буфер, управляемый массивом байтов, который автоматически увеличивается по мере записи данных.
Выходной поток конвейера PipedOutputStream: выходной поток конвейера, который является отправляющим концом конвейера.
Выходной поток примитивного типа ObjectOutputStream: этот класс сериализует сериализованный объект и записывает его в указанное место.
FilterOutputStream фильтровать выходной поток: оболочка для других выходных потоков.
Поток печати PrintStreamТекст можно распечатать в файл или в сеть через PrintStream.
DataOutputStream: Потоки вывода данных позволяют приложениям записывать базовые типы данных Java в базовый поток вывода машинно-независимым способом.
Читатель и его подклассы
Входной поток символов файла FileReader: преобразовать файл в поток символов и прочитать его.
Входной поток массива символов CharArrayReader: это реализация входного потока, который принимает массив символов в качестве источника
Входной поток буфера BufferedReader: класс BufferedReader считывает текст из потока ввода символов и буферизует символы для эффективного чтения символов, массивов и строк.
PushbackReader: Класс PushbackReader позволяет вернуть один или несколько символов обратно во входной поток.
Входной поток канала PipedReader: Основная цель также состоит в том, чтобы общаться между потоками, но это может быть использовано для передачи символов.
Writer и его подклассы
Поток вывода символов FileWriter: FileWriter создает класс Writer, который может записывать в файл.
Поток вывода массива символов CharArrayWriter: CharArrayWriter реализует выходной поток, нацеленный на массив.
Выходной поток буфера BufferedWriter: BufferedWriter добавленflush( )
Метод Писателя. Метод flush() может использоваться для гарантии того, что буфер данных действительно записывается в фактический выходной поток.
PrintWriter: PrintWriter — это, по сути, символьная версия PrintStream.
Выходной поток канала PipedWriter: Основная цель также состоит в том, чтобы общаться между потоками, но это может быть использовано для передачи символов.
Потоковый интерфейс Java для ввода и вывода обеспечивает аккуратную абстракцию для сложных и тяжелых задач. Сочетание классов отфильтрованных потоков позволяет динамически создавать интерфейсы потоковой передачи на стороне клиента в соответствии с требованиями к передаче данных. Java-программы, наследующие потоковые классы более высокого уровня InputStream, InputStreamReader, Reader и Writer, можно разумно использовать в будущем (даже если будут созданы новые и улучшенные конкретные классы).
аннотация
Java 注解(Annotation)
Также известен как元数据
, который предоставляет нам формальный способ добавления информации в наш код. Он был представлен в JDK1.5, Java определяет набор аннотаций, всего 7, 3 вjava.lang
, остальные 4 находятся вjava.lang.annotation
середина.
Есть три аннотации, которые действуют на код:
-
@Override
: тег перезаписи обычно используется после того, как подкласс наследует родительский класс, и помечается в переопределенном методе подкласса. Если обнаружится, что его родительский класс или указанный интерфейс не имеют этого метода, будет сообщено об ошибке компиляции. -
@Deprecated
: код, аннотированный этой аннотацией, устарел и объявлен устаревшим. -
@SuppressWarnings
: Эта аннотация играет роль игнорирования предупреждений компилятора.
Существует четыре мета-аннотации, а мета-аннотации — это аннотации, используемые для обозначения аннотаций. они соответственно
-
@Retention
: как хранится удостоверение, находится ли оно только в коде, скомпилировано в файл класса или может быть доступно через отражение во время выполнения.
RetentionPolicy.SOURCE: аннотация сохраняется только в исходном файле.Когда файл Java компилируется в файл класса, аннотация отбрасывается;
RetentionPolicy.CLASS: аннотации сохраняются в файле класса, но отбрасываются, когда jvm загружает файл класса, это默认的
жизненный цикл;
RetentionPolicy.RUNTIME: аннотация не только сохраняется в файле класса, но и существует после того, как JVM загрузит файл класса;
-
@Documented
: Отмечает, включены ли эти аннотации в JavaDoc. -
@Target
: Отметьте эту аннотацию, чтобы описать область действия объекта, измененного аннотацией.Аннотацию можно использовать для пакетов, типов (классы, интерфейсы, перечисления, типы аннотаций), членов типа (методы, конструкторы, переменные-члены, значения перечисления), методы Параметры и локальные переменные (например, переменные цикла, параметры захвата). Значения следующие
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
-
@Inherited
: Отметьте, от какого класса аннотаций унаследована эта аннотация.
Начиная с JDK1.7, были добавлены три дополнительные аннотации:
-
@SafeVarargs
: Компилятор Java выдает непроверенное предупреждение при объявлении конструктора или метода с переменным числом аргументов. Используйте @SafeVarargs, чтобы игнорировать эти предупреждения. -
@FunctionalInterface
: указывает, что метод является функциональным интерфейсом -
@Repeatable
: указывает, что аннотацию можно использовать несколько раз в одном и том же объявлении.
Примечание. Аннотации не поддерживают наследование.
Несколько способов борьбы с нулем
Нулевые указатели всегда были раздражающей проблемой для Java-программистов, и мы часто сталкиваемся с NullPointerException в процессе разработки. Изобретатель Java также признал, что это была огромная ошибка проектирования.
Итак, что касается null , вы должны знать следующие вещи, чтобы эффективно понимать null и избегать многих ошибок, вызванных null .
Деликатный случай
Во-первых, null есть в Java.关键字
, например **public, static, final. ** Это чувствительно к регистру, вы не можете написать null как Null или NULL, редактор не распознает их и сообщит об ошибке.
Эта проблема почти никогда не возникает, потому что компиляторы eclipse и Idea уже дают подсказки компилятору, поэтому вам не нужно об этом думать.
null — начальное значение любого ссылочного типа
Null является значением по умолчанию для всех ссылочных типов, и любая ссылочная переменная в Java принимает значение null в качестве значения по умолчанию, что означает, что значение по умолчанию для всех ссылочных типов в классе Object равно null. Это относится ко всем ссылочным переменным. Так же, как и значения по умолчанию для примитивных типов, например, значение по умолчанию для int равно 0, а значение по умолчанию для логического значения — false.
Ниже приведены начальные значения примитивных типов данных.
null - это просто специальное значение
null не является ни объектом, ни типом, это просто специальное значение, вы можете присвоить его любому типу, вы можете привести null к любому типу
public static void main(String[] args) {
String str = null;
Integer itr = null;
Double dou = null;
Integer integer = (Integer) null;
String string = (String)null;
System.out.println("integer = " + integer);
System.out.println("string = " + string);
}
Вы можете видеть, что приведение null к любому ссылочному типу возможно во время компиляции и во время выполнения без создания исключения нулевого указателя.
null может быть присвоен только ссылочным переменным, а не переменным примитивного типа.
Когда класс-оболочка, содержащий null, автоматически распаковывается, преобразование не может быть завершено, и возникает исключение нулевого указателя, а null нельзя сравнивать с базовым типом данных.
public static void main(String[] args) {
int i = 0;
Integer itr = null;
System.out.println(itr == i);
}
используется переменная ссылочного типа с нулевым значением,instanceof
Операция вернет false
public static void main(String[] args) {
Integer isNull = null;
// instanceof = isInstance 方法
if(isNull instanceof Integer){
System.out.println("isNull is instanceof Integer");
}else{
System.out.println("isNull is not instanceof Integer");
}
}
Это важная особенность оператора instanceof, которая делает его полезным для проверки приведения типов.
Вызов статического метода с нулевой статической переменной не приведет к возникновению исключения NullPointerException. Поскольку статические методы используют статическую привязку.
Используйте нулевой безопасный метод
Вы должны использовать нулевые безопасные методы.В библиотеке классов java есть много классов инструментов, которые предоставляют статические методы, такие как классы-оболочки для базовых типов данных, Integer , Double и так далее. Например
public class NullSafeMethod {
private static String number;
public static void main(String[] args) {
String s = String.valueOf(number);
String string = number.toString();
System.out.println("s = " + s);
System.out.println("string = " + string);
}
}
номер не имеет назначения, поэтому по умолчанию он равен нулю, используйтеString.value(number)
Статические методы не генерируют исключения нулевого указателя, а используютtoString()
Он генерирует исключение нулевого указателя. Поэтому попробуйте использовать статические методы объектов.
нулевое решение
ты можешь использовать==
или!=
операции для сравнения нулевых значений, но не могут использовать другие арифметические или логические операции, такие как меньше или больше. В отличие от SQL, в Java null == null вернет true, например:
public class CompareNull {
private static String str1;
private static String str2;
public static void main(String[] args) {
System.out.println("str1 == str2 ? " + str1 == str2);
System.out.println(null == null);
}
}
О интеллект-картах
Для удобства читателей я обобщил интеллект-карты некоторых часто используемых наборов инструментов Java.