Ініціалізація змінних у методах класу. Ініціалізація полів (членів даних) класу. Способи ініціалізації членів даних класу
Дана тема демонструє способи ініціалізації внутрішніх членів даних класу у мові програмування Java.
Зміст
- 1. Поняття ініціалізації змінних у методах в Java
- 2. Які існують способи ініціалізації членів даних класу?
- 3. Ініціалізація полів даних класу. Що таке ініціалізація полів даних класу за замовчуванням?
- 4. Які значення за замовчуванням присвоюються полям класу для різних типів?
- 5. Яким значенням ініціалізується змінна-посилання на об’єкт класу?
- 6. Явна ініціалізація. Яким чином здійснюється явна ініціалізація членів даних класу початковими значеннями?
- 7. Яким чином здійснюється явна ініціалізація членів даних класу, що є змінними-посиланнями на клас
- 8. Явна ініціалізація з допомогою виклику методів. Яким чином ініціалізується значення члена даних класу з допомогою виклику методу?
- 9. Який порядок ініціалізації при оголошенні змінних? Яке значення має порядок ініціалізації при оголошенні змінних? Приклади
- 10. Яким чином здійснюється ініціалізація з допомогою конструктора?
- 11. Яким чином можна ініціалізувати члени даних класу з допомогою секції ініціалізації { }? Приклад
- 12. Що виконується першим: секція ініціалізації чи конструктор класу?
- Зв’язані теми
Пошук на інших ресурсах:
1. Поняття ініціалізації змінних у методах в Java
Ініціалізація змінної означає явне (або неявне) встановлення деякого значення змінній.
У мові програмування Java змінні, що оголошені в методі, обов’язково мають бути ініціалізовані перед їх використанням.
Якщо у тілі деякого методу класу, спробувати використати оголошену, але не ініціалізовану змінну, то компілятор видасть помилку.
Наприклад. У нижченаведеному фрагменті коду відбувається спроба використати змінну t, яка оголошена але не ініціалізована
static void SomeMethod() { int t; int x; x = 6; x = x + t + 2; // тут помилка: змінна t не ініціалізована }
У цьому випадку видається повідомлення про помилку:
The local variable t may not have been initialized
Щоб виправити ситуацію, потрібно змінній t присвоїти якесь значення перед її використанням.
2. Які існують способи ініціалізації членів даних класу?
В Java можна ініціалізувати змінну, якщо вона є членом даних класу. Існує чотири способи ініціалізації членів даних класу:
- ініціалізація за замовчуванням (неявна ініціалізація);
- явна ініціалізація початковими значеннями (константними значеннями);
- явна ініціалізація методами класу;
- ініціалізація з допомогою конструкторів класів.
3. Ініціалізація полів даних класу. Що таке ініціалізація полів даних класу за замовчуванням?
Якщо змінна є членом даних класу, то ця змінна ініціалізується значенням за замовчуванням при її оголошенні.
Тобто, якщо є клас в якому оголошені внутрішні змінні (поля класу)
class SomeClass { int d; double x; // ... }
то ці змінні (d, x) будуть ініціалізовані значенням за замовчуванням. У вищенаведеном коді змінним за замовчуванням буде присвоєно наступні значення
d = 0.0 x = 0
Немає значення, який ідентифікатор доступу використовується для змінної (private, protected, public).
4. Які значення за замовчуванням присвоюються полям класу для різних типів?
При оголошенні в класі змінної, цій змінній присвоюються значення за замовчуванням. Нижче наведено значення за замовчуванням, які присвоюються змінним різних типів
int => 0 boolean => false double => 0.0 float => 0.0 char => ' ' - нуль-символ long => 0 byte => 0
Символьній змінній типу char присвоюється нуль-символ, який відображається у вигляді символу “пробіл”.
5. Яким значенням ініціалізується змінна-посилання на об’єкт класу?
Якщо у класі оголошується змінна-посилання на об’єкт деякого класу, то за замовчуванням, значення цього посилання рівне null.
Нижченаведений фрагмент коду демонструє це.
// деякий клас public class InnerClass { // ... } // клас, в якому оголошено об'єкт класу InnerClass public class MyClass { // ... public static InnerClass obj; // obj = null; - за замовчуванням // ... }
У вищенаведеному прикладі змінна obj є посиланням (reference) на клас InnerClass. Іншими словами obj це об’єкт класу InnerClass. Оскільки, пам’ять для obj ще не виділена, то за замовчуванням значення obj = null.
6. Явна ініціалізація. Яким чином здійснюється явна ініціалізація членів даних класу початковими значеннями?
Явна ініціалізація означає задавання початкового (потрібного) значення змінній при її оголошенні в класі.
Наприклад. У класі MyClass реалізована ініціалізація початковими значеннями змінних різних типів.
public class CTrain01 { // явна ініціалізація початкових значень змінних int d = 25; // явна ініціалізація змінної d типу int значенням 25 float y = 3.885f; public double x = -129.48; boolean b = true; char c = 'Z'; long l = 0xF3309FA; // ... }
7. Яким чином здійснюється явна ініціалізація членів даних класу, що є змінними-посиланнями на клас
Якщо членом даних класу є змінна-посилання на деякий клас (об’єкт класу), то вона ініціалізується стандартним способом з допомогою оператора new:
class InnerClass { // ... } class MyClass { // ... // явна ініціалізація змінної obj в класі MyClass InnerClass obj = new InnerClass(); // ... }
У класі MyClass змінна-посилання obj перед її використанням обов’язково має бути ініціалізована оператором new. Якщо спробувати використати неініціалізовану змінну, яка є посиланням на клас, виникне критична ситуація (виключення).
8. Явна ініціалізація з допомогою виклику методів. Яким чином ініціалізується значення члена даних класу з допомогою виклику методу?
При оголошенні, члени даних класу можуть бути ініціалізовані викликом деякого методу.
Наприклад. Нехай задано клас CRadius. У класі CRadius ініціалізуються члени даних len, area, volume з допомогою виклику методів Length(), Area(), Volume(). Ці методи обчислюють відповідно довжину кола, площу круга та об’єм кулі радіусу r, що є вхідним параметром.
public class CRadius { // приховані змінні private double Pi = 3.1415; private double radius=1; // загальнодоступні змінні public double len = Length(radius); // ініціалізація змінної len методом Length() public double area = Area(radius); // ініціалізація змінної area методом Area() public double volume = Volume(radius); // ініціалізація змінної volume методом Volume() // методи обчислення double Length(double r) { return 2*Pi*r; } double Area(double r) { return Pi*r*r; } double Volume(double r) { return 4.0/3.0*Pi*r*r*r; } public static void main(String[] args) { // демонстрація ініціалізації методами класу CRadius CRadius r1 = new CRadius(); // явна ініціалізація членів даних об'єкту r1 double l, a, v; l = r1.len; // l = 6.283; a = r1.area; // a = 3.1415 v = r1.volume; // v = 4.1886666666 } }
9. Який порядок ініціалізації при оголошенні змінних? Яке значення має порядок ініціалізації при оголошенні змінних? Приклади
У класі змінні ініціалізуються в першу чергу. Ініціалізація змінних відбувається навіть перед викликом конструктору класу. Порядок ініціалізації змінних визначається порядком їх оголошення у класі (див. приклад 1). Після ініціалізації змінних викликається конструктор. При цьому, оголошення та ініціалізація змінних можуть бути реалізовані у будь-якому місці класу (див. приклад 2).
Як видно з програмного коду у пункті 8, змінні оголошуються у строго визначеній послідовності, в якій значення ініціалізуючих змінних та методів (справа від операції присвоєння) було визначене на момент ініціалізації.
Приклад 1. Нехай задано клас CInitOrderClass, у якому значення наступного члена даних ініціалізується значенням попереднього члена даних або методу.
// у класі демонструється правильний порядок ініціалізації public class CInitOrderClass { int t1 = 5; int t2 = SomeMethod(); // t2 = 100; int t3 = t2; // t3 = 100 int t4 = t1 + t3; // t4 = 5 + 100 = 105 int t5 = SomeMethod() + t4; // t5 = 205 // метод, що використовується при ініціалізації int SomeMethod() { return 100; } public static void main(String[] args) { // Демонстрація використання об'єкту класу CInitOrderClass CInitOrderClass obj = new CInitOrderClass(); int d; d = obj.t1; // d = 5 d = obj.t2; // d = 100 d = obj.t3; // d = 100 d = obj.t4; // d = 105 d = obj.t5; // d = 205 } }
Якщо у класі змінити порядок оголошення та ініціалізації, то може виникнути помилка. Наприклад, якщо оголошення змінної t4 помістити на самий верх оголошень членів даних класу:
public class CInitOrderClass { int t4 = t1 + t3; // t4 = ??? - тут помилка, змінні t1, t3 ще не оголошені int t1 = 5; int t2 = SomeMethod(); // t2 = 100; int t3 = t2; // t3 = 100 int t5 = SomeMethod() + t4; // t5 = 205 // ... }
то виникне помилка компіляції
Cannot reference a field before it is defined
Це є логічним, оскільки перегляд оголошень змінних відбувається зверху-донизу (з початку до кінця). На момент оголошення змінної t4, змінні t1 та t3 які беруть участь в ініціалізації ще не оголошені. Це є причиною виникнення помилки.
Це не стосується методу класу SomeMethod(), який може використовуватись при ініціалізації у будь-якому місці класу.
Приклад 2. Даний приклад демонструє правило, в якому будь-яка внутрішня змінна класу (член даних класу) ініціалізується першою, навіть перед викликом конструктора.
Нехай дано реалізацію класу COrderInit, в якому ініціалізуються три змінні a, b, c з допомогою методу InitMethod() та з допомогою конструктора COrderInit().
// у класі демонструється порядок ініціалізації public class COrderInit { int a = InitMethod("a = "); // ініціалізація змінної a з допомогою методу // ініціалізація змінних конструктором COrderInit() { a = b = c = 0; System.out.println("Constructor COrderInit()."); } int c = InitMethod("c = "); //ініціалізація змінної c // метод, що ініціалізує змінні int InitMethod(String s) { System.out.println(s + "InitMethod()."); return 100; } int b = InitMethod("b = "); // ініціалізація змінної b public static void main(String[] args) { COrderInit obj = new COrderInit(); } }
Як видно з вищенаведеного коду, клас містить функцію main(), в якій створюється об’єкт класу COrderInit. Метод класу InitMethod() отримує вхідним параметром рядок s. Цей рядок виводить рядок ініціалізації з іменем відповідної змінної.
У результаті виконання такого коду буде виведено наступний результат:
a = InitMethod(). c = InitMethod(). b = InitMethod(). Constructor COrderInit().
Результат показує, що першою відбувається ініціалізація змінних a, c, b. Порядок ініціалізації змінних визначається порядком їх оголошення в класі. Після цього відбувається виклик конструктора.
10. Яким чином здійснюється ініціалізація з допомогою конструктора?
Ініціалізація членів даних класу з допомогою конструктора більш детально описується в темі:
11. Яким чином можна ініціалізувати члени даних класу з допомогою секції ініціалізації { }? Приклад
Члени даних класу можна ініціалізувати в одній секції, як показано у прикладі.
public class CDataInit { int a, b, c, d; // ініціалізація з допомогою секції ініціалізації { } { a = 1; b = 2; c = 3; d = 4; } public static void main(String[] args) { CDataInit obj = new CDataInit(); int t; t = obj.a; // t = 1 t = obj.b; // t = 2 t = obj.c; // t = 3 t = obj.d; // t = 4 } }
12. Що виконується першим: секція ініціалізації чи конструктор класу?
Першою виконується секція ініціалізації а потім конструктор.
Зв’язані теми
- Ініціалізація статичних членів даних. Статичний блок. Ініціалізація одновимірних та багатовимірних масивів
- Конструктори. Параметризовані конструктори. Ключове слово this. Збір “сміття”. Метод finalize(). Приклади
- Конструктори за замовчуванням (default constructors). Виклик конструкторів класу з інших конструкторів