Некоторые вопросы о статических конструкторах, методах и полях - PullRequest
1 голос
/ 14 сентября 2010

У меня есть несколько вопросов о поведении статических членов:

1) Есть ли разница при инициализации статических полей и статических конструкторов? Насколько мне известно, статические поля инициализируются при выполнении программы. Действуют ли члены статических конструкторов одинаково или инициализируются при первом использовании:

MyClass.myStaticField;

или я должен сначала инициализировать MyClass:

Myclass m = new MyClass();  // static constructor is called
MyClass.myStaticField;      // and after that

2) Насколько я помню, статические поля не являются сборщиком мусора? Так это причина, почему я не должен использовать статические методы? Когда я читал об этой теме, большинство людей утверждали, что вы должны использовать статические методы, когда вы можете выбирать между статическим и нестатическим.

3) Есть ли какие-либо проблемы, на которые следует обратить внимание, когда вы производите класс от родительского класса, имеющего статический конструктор?

4) Из любопытства, вы можете утилизировать статический член?

Ответы [ 6 ]

3 голосов
/ 14 сентября 2010

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

Статические поля - это сборщик мусора, как и обычные значения.То есть они собираются, когда к ним больше нельзя получить доступ.Это может произойти в ряде сценариев, наиболее распространенным из которых является разгрузка AppDomain.Статические поля специфичны для AppDomain, поэтому, как только он выгружается, его члены пригодны для сбора (это может отличаться для AppDomain нейтральных типов, но я не верю в это).

Распределение статического элемента совершенно законно, хотя это может привести к некоторым проблемам, если вы оставите значение disposed в поле и, следовательно, будете доступны для остальной части приложения (которое может не осознавать, что оно утилизировано)

1 голос
/ 14 сентября 2010

Вы также пометили это как Java, так что пара перспектив Java.

1).В Java нет концепции статического конструктора, вместо этого вы можете определить блоки кода как статические, и они запускаются в то время, когда класс готов к использованию - в конце концов, статические поля являются общими для всех экземпляров класса и поэтому необходимоне может быть инициализирован до того, как у нас будут какие-либо рабочие экземпляры.

2).Не думайте о полях, статических или иных, как о сборщике мусора - это объекты, которые собирают мусор.Так что если у вас есть:

 class MyClass {

        private static OneThing x = new OneThing();
        private Another y = new Another();            
 } 

 // some code

     MyClass m = new MyClass();  // creates instance of MyClass
     m = null;

// no one now references that instance of MyClass

Вы не собираете мусор x и y, вы собираете мусор OneThing и Another.Это произойдет, когда на эти объекты не будет ссылок.

В случае объекта Another, на который ссылается y, это происходит, когда сам экземпляр MyClass собирается сборщиком мусора.Но OneThing, на который ссылается x, будет по-прежнему ссылаться до тех пор, пока MyClass известен JVM.НО, сами классы могут быть сборщиком мусора, поэтому возможно, что в конечном итоге эта ссылка x будет удалена, а объект OneThing будет собран сборщиком мусора.

1 голос
/ 14 сентября 2010

Статические и экземплярные (нестатические) поля имеют очень разные значения, и важно понять их, прежде чем решить, какой из них использовать.

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

public class MyClass {
   static int myInt = 5;
}

System.out.println(MyClass.myInt); // this prints 5
MyClass.myInt = 10;
System.out.println(MyClass.myInt); // this prints 10

Для переменной экземпляра требуется экземпляр класса

public class MyClass {
    private int myInt2;

    public void setMyInt2(int val) {
        myInt2 = val;
    }

    public int getMyInt2() {
        return myInt2;
    }
}

MyClass m1 = new MyClass();
MyClass m2 = new MyClass();
System.out.println(m1.getMyInt2()); // prints 0, the default value
System.out.println(m2.getMyInt2()); // prints 0, the default value
m1.setMyInt2(3);
m2.setMyInt2(5);
// each object operates on its own instance of the variable
System.out.println(m1.getMyInt2()); // prints 3
System.out.println(m2.getMyInt2()); // prints 5

Также нет такой вещи, как static constructor. Есть конструкторы, а также статические блоки инициализатора. Статический блок инициализатора записывается как:

static {
   // initialize some static members here
}

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

1 голос
/ 14 сентября 2010

Статические методы не защищены от сборки мусора.Используйте все, что вам нравится.

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

0 голосов
/ 14 сентября 2010

Что касается # 1, в Java все равно очевидно, что вам не нужно создавать экземпляры класса для использования статических членов.Это предотвратит возможность иметь класс, который не предназначен для создания экземпляра (например, java.util.Collections).

Кроме того, у вас будет противоречие с наиболее распространенным шаблоном синглтона:

 public SomeSingletonClass {
     public static final SomeSingletonClass instance = new SomeSingletonClass();
     private SomeSingletonClass() {}
 }
0 голосов
/ 14 сентября 2010
  1. Все статические конструкторы / инициализаторы происходят одновременно (хотя поля инициализируются в зависимости от того, когда к ним обращаются).
  2. Статические методы никогда не создаются - они представляют поведение, а не состояние. Поэтому они не участвуют в сборке мусора.
  3. Нет. Будет вызван статический конструктор базового класса, но это вряд ли проблема.
  4. Что вы подразумеваете под распоряжением? C # IDisposable? Ответ - да, если в статическом поле содержится экземпляр чего-либо, реализующего этот интерфейс.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...