﻿# V6050\. Class initialization cycle is present\.

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

**Случай 1\. **

Использование статического поля до того, как оно будет проинициализировано\.

Рассмотрим синтетический пример некорректного кода:

```cpp
public class Purse
{
  static private Purse reserve = new Purse(10);
  static private int scale = 5 + (int) (Math.random() * 5);

  private int deposit;

  Purse() {
    deposit = 0;
  }
  
  Purse(int initial) {
    deposit = initial * scale;
  }
  ...
}
```

Как известно, статические поля будут инициализироваться в порядке объявления самыми первыми при первом использовании класса\. Следовательно, в данном примере сначала инициализируется 'reserve', а потом 'scale'\.

Рассмотрим инициализацию статического поля 'reserve':

* Вызывается конструктор 'Purse' с аргументом 'initial \= 10'\.
* На момент выполнения выражения 'initial \* scale' в вызываемом конструкторе, поле 'scale' еще не инициализировано, и будет равно значению по умолчанию \(0\), вместо значения из диапазона \[5;10\]\.

Вследствие чего, поле 'deposit' у объекта 'reserve' будет проинициализировано не так, как задумывалось\.

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

```cpp
public class Purse
{
  static private int scale = 5 + (int) (Math.random() * 5);
  static private Purse reserve = new Purse(10);
  
  private int deposit;

  Purse() {
    deposit = 0;
  }
  
  Purse(int initial) {
    deposit = initial * scale;
  }
  ...
}
```

**Случай 2\. **

Взаимная зависимость статических полей разных классов\.

Рассмотрим синтетический пример некорректного кода:

```cpp
public class A {
  public static int scheduleWeeks = B.scheduleDays / 7 + 1;
  ....
}
....
public class B {
  public static int scheduleDays = A.scheduleWeeks * 7 + 7;
  ....
}
```

Ситуация здесь такова, что статическое поле 'A\.scheduleWeeks' зависит от статического поля 'B\.scheduleDays', и наоборот\. Порядок инициализации классов может меняться, отсюда меняется и порядок инициализации статических полей\. Если инициализируется первым класс 'A', то 'A\.scheduleWeeks' будет иметь значение 2, а 'B\.scheduleDays' – 7\. Если первым будет класс 'B', то 'A\.scheduleWeeks' будет равен 1, а 'B\.scheduleDays' – 14\. Вряд ли такое поведение будет приятно наблюдать у себя в коде\. В таком случае необходимо пересмотреть инициализацию этих полей и убрать зависимость друг от друга\.

Например, можно одно из статических полей инициализировать константой, и эта зависимость исчезнет:

```cpp
public class A {
  public static int scheduleWeeks = B.scheduleDays / 7 + 1;
  ....
}
....
public class B {
  public static int scheduleDays = 14;
  ....
}
```

В таком случае 'B\.scheduleDays' всегда будет равен 14, а 'A\.scheduleWeeks' – 3\.

**Случай 3\.**

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

Рассмотрим синтетический пример некорректного кода:

```cpp
public class A {
  public static int scheduleWeeks = B.getScheduleWeeks();
  public static int getScheduleDays() { return 21; }
  ....
}
....
public class B {
  public static int getScheduleWeeks() {return A.getScheduleDays()/7;}
  ....
}
```

Независимо от того, какой из классов первым будет инициализирован, поле 'A\.scheduleWeeks' примет значение равное 3\. Несмотря на это, такой способ инициализации сбивает с толку при чтении и поддержке такого кода\.

Например, можно подкорректировать код следующим образом:

```cpp
public class A {
  public static int scheduleWeeks = B.getScheduleWeeks();
  
  ....
}
....
public class B {
  public static int getScheduleDays() { return 21; }
  public static int getScheduleWeeks() {return B.getScheduleDays()/7;}
}
```