На этот вопрос уже есть ответ:
В чем смысл «инициализаторов экземпляров» в Java?
Разве мы не можем вместо этого поместить этот блок кода в начало конструктора?
Вы действительно можете поместить код в начало каждого конструктора. Однако в этом и заключается смысл инициализатора экземпляра: его код применяется ко всем конструкторам , что может быть полезно, если у вас много конструкторов и немного кода, который является общим для всех них.
(Если вы только начинаете с программирования, вы, возможно, не знали, что можно создать много конструкторов для одного и того же класса (если они принимают разные параметры); это известно как перегрузка конструктора . Если у вас есть только один конструктор, то инициализатор экземпляра действительно не очень полезен (Правка: если вы не злоупотребляете им в творческой моде, как показано в других ответах).)
Поскольку во всех примерах кода здесь используются анонимные классы, я собрал этот (немного ужасающий) класс, который демонстрирует использование инициализаторов экземпляров в «правильном» классе. Вы можете использовать их для сложной обработки или обработки исключений во время инициализации. Обратите внимание, что эти блоки запускаются до запуска конструктора, , но конструктор запускается до запуска инициализаторов в дочернем классе:
import java.util.Scanner;
public class InstanceInitializer {
int x;
{
try {
System.out.print("Enter a number: ");
x = Integer.parseInt(new Scanner(System.in).nextLine());
} catch (NumberFormatException e) {
x = 0;
}
}
String y;
{
System.out.print("Enter a string: ");
y = new Scanner(System.in).nextLine();
for(int i = 0; i < 3; i++)
y += y;
}
public InstanceInitializer() {
System.out.println("The value of x is "+x);
System.out.println("The value of y is "+y);
}
public static class ChildInstanceInitializer extends InstanceInitializer {
{
y = "a new value set by the child AFTER construction";
}
}
public static void main(String[] args){
new InstanceInitializer();
new InstanceInitializer();
System.out.println();
System.out.println(new ChildInstanceInitializer().y);
// This is essentially the same as:
System.out.println(new InstanceInitializer(){
{y = "a new value set by the child AFTER construction";}
}.y);
}
}
Это выводит (что-то вроде):
Enter a number: 1
Enter a string: a
The value of x is 1
The value of y is aaaaaaaa
Enter a number: q
Enter a string: r
The value of x is 0
The value of y is rrrrrrrr
Enter a number: 3
Enter a string: b
The value of x is 3
The value of y is bbbbbbbb
a new value set by the child AFTER construction
Enter a number: s
Enter a string: Hello
The value of x is 0
The value of y is HelloHelloHelloHelloHelloHelloHelloHello
a new value set by the child AFTER construction
Обратите внимание, что строка «новое значение» не устанавливается, пока не будет вызван конструктор родительского класса.