Java static variable init

Инициализация статических членов данных. Статический блок. Инициализация массивов

Если в классе объявлен статический член данных, то он всегда существует в одном экземпляре, независимо от количества создаваемых объектов класса. Статический член данных может быть объявлен как член данных класса:

class MyClass <  static int d; // статический член данных класса  static float x; // статический член данных класса . >

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

Ниже приведены значения по умолчанию, которые присваиваются статическим членам данных в случае отсутствия явной инициализации

static int i; // i = 0 static boolean b; // b = false static float f; // f = 0.0 static double d; // d = 0.0 static char c; // c = символ с кодом 0 static CDate objDate; // objDate = null

Если нужно осуществить явную инициализацию статического члена данных в месте его объявления, тогда это осуществляется точно так же как и для нестатического члена данных:

class MyClass < static int d = 25; // инициализация статического члена данных конкретным значением static float x = 108.35; . >

Более подробно работа со статическими членами данных в Java освещается в теме:

2. Пример инициализации статических членов данных класса. Инициализация статического члена данных с помощью метода

В примере объявляется два класса с именами CDate и CStaticData . В классе CStaticData статические члены данных класса инициализируются так же как и нестатические члены данных класса.

// инициализация статических членов данных класса public class CStaticData < // инициализация статических членов класса  static int i = 2588;  static boolean b = true;  static float f = 3.23f;  static double d = -10.2093; // инициализация статического объекта (экземпляра) класса  static CDate objDate = new CDate(); // инициализация статического члена класса с помощью метода класса GetPi()  static double Pi = GetPi(); // метод GetPi() класса также может быть статическим  static double GetPi() < return 3.1415; >  public static void main(String[] args) < CStaticData obj = new CStaticData(); obj.b = false; CStaticData.d = -10.223; > >

Как видно из примера, чтобы инициализировать статический член данных класса Pi с помощью метода GetPi() , этот метод может быть также объявлен как статический.

3. Какой порядок инициализации, если в классе объявляются статические и нестатические члены данных класса?

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

Пример. Объявляется класс CDataInit , в котором в произвольном порядке инициализируются статические и нестатические члены данных класса.

public class CDataInit < // внутренние функции, которые используется при инициализации  int GetInt(String s) < System.out.println("Non-static initialization of " + s);  return 100; >  static int GetIntStatic(String s) < System.out.println("Static initialization of " + s);  return 5; > // переменные, которые должны быть инициализированы - объявлены в произвольном порядке  int i1 = GetInt("i1");  static int si1 = GetIntStatic("si1");  int i2 = GetInt("i2");  int i3 = GetInt("i3");  static int si2 = GetIntStatic("si2");  int i4 = GetInt("i4");  static int si3 = GetIntStatic("si3");  public static void main(String[] args) < CDataInit obj = new CDataInit(); > >

После объявления объекта класса CDataInit выводятся следующие строки:

Static initialization of si1 Static initialization of si2 Static initialization of si3 Non-static initialization of i1 Non-static initialization of i2 Non-static initialization of i3 Non-static initialization of i4

Как видно из приведенного выше результата, первыми инициализируются статические члены данных.

Читайте также:  Python регулярные выражения регистронезависимый
4. Что такое статический блок? Общая форма

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

Общая форма статического блока:

static < // операции, которые инициализируют статические члены класса // . >

В классе статический блок выглядит приблизительно следующим образом:

class ClassName < .  static < // инициализация статических членов данных класса // . > . >
5. Пример использования статического блока

В классе CDataInit объявляется статический блок, в котором инициализируются статические переменные a , b , c , d .

public class CDataInit <  static int a, b, c, d; // инициализация с помощью статического блока  static <  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 > >
6. Сколько раз вызывается статический блок? В каких случаях вызывается статический блок?

Статический блок вызывается только один раз в одном из двух случаев:

  • при первом создании объекта этого класса;
  • при первом обращении к статическим членам этого класса.

Пример. Пусть задан класс CDataInit , который содержит объявление статических членов с именами a , b , c , d .

public class CDataInit <  static int a, b, c, d; // инициализация с помощью статического блока  static <  a = InitMethod("a color: #0000ff;"> b = InitMethod("b color: #0000ff;"> c = InitMethod("c color: #0000ff;"> d = InitMethod("d color: #993366;"> static int InitMethod(String s) < System.out.println(s + "100");  return 100; >  public static void main(String[] args) < // создание объекта - вызывается статический блок CDataInit obj = new CDataInit(); CDataInit obj2 = new CDataInit(); // второй раз статический блок не вызывается > >

В результате выполнения этого кода, будет выведен результат:

a = 100 b = 100 c = 100 d = 100

Как видно, в функции main() создается два объекта, а инициализированные данные выводятся только один раз. Это подтверждает правило, которое гласит: статические члены данных инициализируются в классе только один раз.

Если в функции main() вместо строки

CDataInit obj = new CDataInit();

ввести код обращения к статической переменной, например

то также будет вызван статический блок инициализации, но только один раз.

7. Инициализация массивов в классе. Как в классе инициализировать массив значениями?

В языке Java массив в классе может быть инициализирован одним из двух способов:

  • непосредственным присваиванием значений массива. В этом случае в фигурных скобках задается набор значений, которые присваиваются массиву;
  • присваиванием ссылки на другой массив. В этом случае присваивается ссылка на другой массив с помощью оператора присваивания ‘=’ .
8. Пример инициализации одномерных массивов в классе

Объявляется класс CInitArray , в котором объявляются массивы a , x и ссылки на них с именами b , y .

public class CInitArray < // инициализация массива в классе // вариант 1 - непосредственная инициализация значениями  int[] a = < 1, 2, 4, 9, -8, 13, 7 >; // в массиве 7 элементов  double x[] = < -1.33, 2.905, 1.308, 10.301, 8 >; // в массиве 5 элементов // вариант 2 - присваивание ссылки  int[] b = a; // массив b ссылается на одно и то же место что и массив a  double[] y = x; // массив y ссылается на x  public static void main(String[] args) < CInitArray M = new CInitArray();  int len; // проверка длины каждого из массивов len = M.a.length; // len = 7 len = M.x.length; // len = 5 // проверка конкретных значений массивов  int d;  double f; d = M.a[3]; // d = 9 f = M.x[2]; // f = 1.308 d = M.b[3]; // d = 9 len = M.b.length; // len = 7 f = M.y[0]; // f = -1.33 len = M.y.length; // len = 5 // изменение в ячейке массива a приводит к изменению в ячейке массива b и наоборот M.a[2] = 100; d = M.b[2]; // d = 100 M.b[0] = -11; d = M.a[0]; // d = -11 // так же, изменение в ячейке массива x приводит к изменению в ячейке массива y, и наоборот M.x[3] = 1.75; f = M.y[3]; // f = 1.75 M.y[1] = -3.22; f = M.x[1]; // f = -3.22 > >

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

Массивы b и y класса инициализируются значениями, которые есть в массивах a , x . Вернее, массивы b и y ссылаются на ячейки массивов a , x .

В функции main() тестируется длина каждого массива и значения элементов массива. Длину каждого массива можно определить с помощью свойства length .

9. Пример инициализации двумерного массива в классе

Инициализация двумерного массива осуществляется точно также как и одномерного.

public class CInitArray < // инициализация двумерного массива в классе // вариант 1 - непосредственная инициализация значениями // объявляется двумерный массив aa размером 4*3  int[][] aa = < < 1, 2, 5 >, < 3, 8, 9 >, < 4, 11, -7 >, < 2, 2, 0 >>; // вариант 2 - присваивание ссылки  int[][] bb = aa; // bb ссылается на aa  public static void main(String[] args) < CInitArray M = new CInitArray();  int len, d; // проверка длин массивов len = M.aa.length; // len = 4 - количество строк len = M.aa[0].length; // len = 3 - количество столбиков в строке с индексом 0 // проверка значений d = M.aa[0][2]; // d = 5 // изменение в ячейке массива a приводит к изменению в ячейке массива b, и наоборот M.aa[0][2] = 13; d = M.bb[0][2]; // d = 13 M.bb[1][0] = 25; d = M.aa[1][0]; // d = 25 > >

Связанные темы

Источник

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

Источник

Оцените статью