Java как инициализировать класс

Инициализация классов в Java

Классы и объекты в Java должны быть инициализированы перед их использованием. Поля класса могут инициализироваться значениями по умолчанию, когда классы загружаются, но есть и другие способы. В данной статье мы рассмотрим все функции Java для инициализации классов.

Перед тем как мы исследуем поддержку в Java для инициализации класса, давайте резюмируем основы инициализации Java. Рассмотрим листинг 1.

Листинг 1. Инициализация полей класса значения по умолчанию

В листинге 1 объявляется класс Up. Этот класс объявляет девять типов полей boolean, byte, char, double, float, int, long, short и String. Когда Up загружен, биты каждого поля устанавливаются в ноль, что вы можете интерпретировать следующим образом:

false 0 \u0000 0.0 0.0 0 0 0 null

Предыдущие поля класса были неявно инициализированы нулем. Тем не менее, вы можете также явно инициализировать поля класса путем непосредственного присвоения им значений, как показано в листинге 2.

Листинг 2. Инициализация полей класса явными значениями

Значение каждой переменной должно быть совместимым по типу с типом поля класса. Каждая переменная хранит значение непосредственно в себе, за исключением st. Переменная st хранит ссылку на String объект, который содержит upread.

Ссылка на объявленные ранее поля

При инициализации поля класса возможно инициализировать его значением ранее инициализированного другого поля класса. Например, в листинге 3 y инициализируетcя x.

Листинг 3. Ссылаемся на ранее объявленное поле

Однако обратное будет неверным: вы не можете инициализировать поле класса еще не объявленным значением. Компилятор Java выведет illegal forward reference, когда встретит листинг 4.

Листинг 4. Попытка сослаться на поле со значением, присвоенным позже

Компилятор будет сообщать о illegal forward reference, когда он встречает static int x = y;. Это происходит потому, что исходный код компилируется сверху вниз, и компилятор еще не видел y . (Также это сообщение было бы выведено, если бы y не была явно инициализирована.)

Инициализация класса блоков

Вы можете выполнять сложные инициализации класса после того, как был загружен класс и прежде, чем любые объекты создаются из этого класса (при условии, что класс не является утилитой класса). Для выполнения этой задачи вы можете использовать блок инициализации класса. Блок инициализации класса представляет собой блок операторов, которым предшествует ключевое слово static. Когда класс загружается, эти операторы выполняются. Рассмотрим листинг 5.

Листинг 5. Инициализация массивов синус и косинус значений

В листинге 5 объявляется класс Up, в котором имеются sin и cos массивы переменных. Он также объявляет блок инициализации класса, который создает 360-элементные массивы, ссылки присваиваются sin и cos. Затем он использует цикл for, чтобы инициализировать эти элементы массива соответствующими синус и косинус значениями, с помощью вызова методов из класса Math — sin() и cos(). (Math является частью стандартной библиотеки классов Java.)

Трюк с производительностью

Поскольку производительность важна для графических приложений, а также потому, что быстрее получить доступ к элементу массива, чем вызвать метод, разработчики прибегают к уловкам производительности, таким как создание и инициализация массивов синусов и косинусов.

Объединение полей классов и инициализация класса блоков

Вы можете объединить несколько инициализаторов полей класса и класса блоков в приложении. В листинге 6 приведен пример.

Листинг 6. Выполнение инициализации класса в порядке сверху вниз

class MCFICIB < static int x = 10; static double temp = 98.6; static < System.out.println("x = " + x); temp = (temp - 32) * 5.0/9.0; // convert to Celsius System.out.println("temp = " + temp); >static int y = x + 5; static < System.out.println("y prettyprint">javac MCFICIB.java

Затем запустите полученное приложение:

Вы должны получить следующее:

Этот вывод показывает, что инициализация класса выполняется в порядке сверху вниз.

При компиляции класса компилятор Java сохраняет байт-код в специальный метод под названием (). Угловые скобки предотвращают конфликт имен, вы не можете объявить () метод в исходном коде , так как символы являются незаконными в контексте идентификатора. После загрузки класса, виртуальная машина вызывает этот метод перед вызовом main() (когда main() присутствует).

Давайте заглянем внутрь MCFICIB.class. Там мы увидим сохраненную информацию для полей x, temp и y:

Field #1 00000290 Access Flags ACC_STATIC 00000292 Name x 00000294 Descriptor I 00000296 Attributes Count 0 Field #2 00000298 Access Flags ACC_STATIC 0000029a Name temp 0000029c Descriptor D 0000029e Attributes Count 0 Field #3 000002a0 Access Flags ACC_STATIC 000002a2 Name y 000002a4 Descriptor I 000002a6 Attributes Count 0

Descriptor определяет дескриптор типа для поля виртуальной машины. Тип представлен одной буквой: I для int и D для double . Следующее частичное дизассемблирование показывает последовательность команд байт-кода для () метода. Каждая строка начинается с десятичного числа, которое идентифицирует с нуля смещение адреса последующей инструкции:

0 bipush 10 2 putstatic MCFICIB/x I 5 ldc2_w #98.6 8 putstatic MCFICIB/temp D 11 getstatic java/lang/System/out Ljava/io/PrintStream; 14 new java/lang/StringBuilder 17 dup 18 invokespecial java/lang/StringBuilder/()V 21 ldc "x temp y prettyprint"> static int x = 10;

Последовательность команд от смещения 5 по смещению 8 эквивалентно следующему инициализатору полей классов:

Последовательность команд от смещения с 11 по 80 смещения эквивалентно следующему блоку инициализации класса:

static < System.out.println("x = " + x); temp = (temp - 32) * 5.0/9.0; // convert to Celsius System.out.println("temp prettyprint">static int y = x + 5;

Последовательность команд от смещения 91 через смещение 115 эквивалентно следующему блоку инициализации класса:

Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

статьи IT, java, классы, теория, инициализация

Источник

Initializing Fields

As you have seen, you can often provide an initial value for a field in its declaration:

public class BedAndBreakfast < // initialize to 10 public static int capacity = 10; // initialize to false private boolean full = false; >

This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate. Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.

Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.

Static Initialization Blocks

A static initialization block is a normal block of code enclosed in braces, < >, and preceded by the static keyword. Here is an example:

A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

There is an alternative to static blocks — you can write a private static method:

The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.

Initializing Instance Members

Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods.

Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:

The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.

A final method cannot be overridden in a subclass. This is discussed in the lesson on interfaces and inheritance. Here is an example of using a final method for initializing an instance variable:

This is especially useful if subclasses might want to reuse the initialization method. The method is final because calling non-final methods during instance initialization can cause problems.

Previous page: Understanding Class Members
Next page: Summary of Creating and Using Classes and Objects

Источник

Читайте также:  Самый большой вид питонов
Оцените статью