Іншими словами, навіщо вам потрібен ініціалізатор примірника? Яка різниця чи перевага у вас при написанні ініціалізатора екземпляра над конструктором?
Іншими словами, навіщо вам потрібен ініціалізатор примірника? Яка різниця чи перевага у вас при написанні ініціалізатора екземпляра над конструктором?
Відповіді:
Здається, це добре пояснює це:
Ініціалізатори екземплярів є корисною альтернативою ініціалізаторам змінних екземплярів, коли:
код ініціалізатора повинен ловити винятки, або
виконувати вигадливі обчислення, які неможливо виразити за допомогою ініціалізатора змінної екземпляра. Звичайно, ви завжди можете написати такий код у конструкторах.
Але в класі, який мав кілька конструкторів, вам доведеться повторити код у кожному конструкторі. За допомогою ініціалізатора екземпляра ви можете просто написати код один раз, і він буде виконаний незалежно від того, який конструктор використовується для створення об’єкта. Ініціатори екземплярів також корисні в анонімних внутрішніх класах, які взагалі не можуть оголошувати жодні конструктори.
З: JavaWorld Об’єкт ініціалізації в Java .
З точки зору життєвого циклу об'єкта різниці немає. Обидва вони викликаються під час побудови, і логічно блок ініціалізатора можна вважати частиною побудови.
Семантично ініціалізатор - це приємний інструмент з кількох причин:
ініціалізатор може покращити читабельність коду, зберігаючи логіку ініціалізації поруч із ініціалізованою змінною:
public class Universe {
public int theAnswer;
{
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
}
// a bunch of other vars
}
проти
public class Universe {
public int theAnswer;
// a bunch of other vars
public Universe() {
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
// other constructor logic
}
}
Ініціалізатори викликаються незалежно від того, який конструктор використовується.
Ініціалізатори можна використовувати в анонімних внутрішніх класах, де конструктори не можуть.
theAnswer
- це оголошена змінна екземпляра. Він ініціалізується в анонімному блоці ініціалізації. Зверніть увагу на крапку з комою після оголошення змінної.
Коли у вас багато конструкторів і ви хочете, щоб для кожного конструктора виконувався якийсь загальний код, ви можете використовувати ініціалізатор екземпляра, оскільки він викликається для всіх конструкторів.
Я б уникнув ідіоми ініціалізатора екземпляра загалом - єдина реальна перевага, яку він дає перед ініціалізаторами змінних, це обробка винятків.
Оскільки метод init (який можна викликати з конструктора) також може виконувати обробку винятків, а також централізує код налаштування конструктора, але має ту перевагу, що він може працювати зі значеннями параметрів конструктора, я б сказав, що ініціалізатор екземпляра є надлишковим, і тому повинен бути уникати.
Реальна перевага примірника ініціалізаторів над конструкторами видно , коли ми використовуємо анонімний внутрішній клас .
Анонімні внутрішні класи не можуть мати конструктор (оскільки вони анонімні) , тому вони цілком природно підходять для ініціалізаторів, наприклад .
Під час створення об'єкта, якщо ми хочемо виконати ініціалізацію змінних екземпляра, тоді нам слід вибрати конструктор, крім активності ініціалізації, якщо ми хочемо виконати будь-яку діяльність під час створення об'єкта, тоді нам слід перейти, наприклад, до блоку.
Ми не можемо замінити конструктор блоком екземпляра, оскільки конструктор може приймати аргументи, але блок екземпляра не може приймати аргументи.
Ми не можемо замінити блок екземплярів з конструктором, оскільки клас може містити більше одного конструктора. Якщо ми хочемо замінити блок екземпляра конструктором, тоді в кожному конструкторі ми повинні писати код блоку екземпляра, оскільки під час виконання, який конструктор буде викликаний, ми не можемо очікувати, це необов’язково збільшить кількість повторюваних кодів.
Приклад:
class MyClass{
static int object_count = 0;
MyClass(){
object_count++;
}
MyClass(int i){
object_count++;
}
void getCount() {
System.out.println(object_count);
}
public static void main(String... args) {
MyClass one = new MyClass();
MyClass two = new MyClass(2);
two.getCount();
}
}
Вихід: 2
class MyClass{
static int object_count = 0;
{
object_count++;
}
MyClass(){
}
MyClass(int i){
}
void getCount() {
System.out.println(object_count);
}
public static void main(String... args) {
MyClass one = new MyClass();
MyClass two = new MyClass(2);
two.getCount();
}
}
Вихід: 2
Ініціалізатор - це спосіб спільного використання коду між конструкторами, і він робить код більш читабельним, якщо ініціалізатор використовується з оголошеннями змінних.
Компілятор Java копіює блоки ініціалізатора в кожен конструктор. Отже, цей підхід можна використовувати для спільного використання коду між кількома конструкторами. Документація Oracle