tags:

views:

106

answers:

6

I have some questions about behaviour of static members:

1) Is there a difference when initializing static fields and static constructors? As of my knowledge static fields are initialized with program execution. Does members of static constructors behave same way, or they are initialized on first use:

MyClass.myStaticField;

or I must initialize MyClass first:

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

2) As I do recall, static fields are not garbage collected? So is this a reason, why I should not be instanciating static methods? When I've read about this topic, most of the people claims, that you should use static methods when, you can choose between static and non-static.

3) Is there any issues that must be pointed when you derive a class from parent class having static constructor?

4) Just of a curiosity, can you dispose static member?

+1  A: 

Static methods are not immune from garbage collection. Use them all you like.

A static field normally isn't garbage collected because it doesn't go out of scope. However, if you were to set a static field to null, the instance it used to reference would then be a candidate for garbage collection. You could even call Dispose on a static field before nulling it out.

Steven Sudit
+2  A: 

The difference between static field and constructor initialization is a bit complex as it's changed between framework versions. Jon did an indepth blog article on this subject that you should take a look at.

Static Fields are garbage collected just like normal values. That is they are collected when they can no longer be accessed. This can happen in a number of scenarios the most common of which is when an AppDomain unloads. Static fields are specific to an AppDomain so once it unloads it's members are eligable for collection (this may be different for AppDomain neutral types but I don't believe so).

It's perfectly legal to Dispose a static member although it can lead to some issues if you leave the disposed value in the field and hence accessible to the rest of the application (which may not realize it's disposed)

JaredPar
A: 
  1. Static constructors/initializers all happen at the same time (though fields get initialzed based on when they get accessed.)
  2. Static methods are never instantiated -- they represent behavior, not state. Therefore they do not participate in garbage collection.
  3. No. The base class' static constructor will be called, but that's hardly an "issue".
  4. What do you mean by dispose? C# IDisposable? The answer is yes if the static field is holding an instance of something that implements that interface.
Kirk Woll
As a clarification, static methods can have local variables, which *are* garbage collected when they go out of scope.
Steven Sudit
+1  A: 

Static and instance (non-static) fields have very different meanings, and it is important to understand them before deciding which to use.

A static variable or method belongs to a class, not to a particular instance of the class. There is one copy of it per class (no matter how many instances you create) and it can be accessed without an instance of the class. For example,

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

An instance variable requires an instance of the class

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

Also, there is no such thing as a static constructor. There are constructors as well as static initializer blocks. A static initializer block is written as:

static {
   // initialize some static members here
}

In general, use instance variables/methods when the values affect an individual instance of an object, and use static variables and methods when they do not.

Jeff Storey
So there is no difference between static { } and http://msdn.microsoft.com/en-us/library/k9x6w0hc%28VS.80%29.aspx
kofucii
Ah, my response is more specific to Java since you tagged is c# and Java. Sorry.
Jeff Storey
In C#, there are static constructors. http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx
Steven Sudit
+1  A: 

You've tagged this as Java too, so a couple of Java perspectives.

1). In Java there is no concept of a static constructor, instead you can define blocks of code as static and they are run at the time the Class is prepared for use - after all, static fields are shared by all instances of the Class and so need t be initialised before we have any working instances.

2). Don't think of fields, static or otherwise, as being garbage collected - it's objects that get garbage collected. So if you have:

 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

You're not garbage collecting x and y, you're garbage collecting the OneThing and Another instances. This will happen when there are no references to those objects.

In the case of the Another referenced by y, that happens when the MyClass instance itself is garbage collected. But OneThing referenced by x will still be referenced for so long as MyClass is known to the JVM. BUT, classes themselves can be garbage collected, so it is possible for eventually that x reference to be removed and the OneThing object to be garbage collected.

djna
A: 

With regards to #1, it's intuitively obvious in Java anyway that you don't need to create instances of the class to use the static members. It would prevent the ability to have a class that is not meant to be instantiated (e.g. java.util.Collections).

Plus you'd have a contradiction with the most common singleton pattern:

 public SomeSingletonClass {
     public static final SomeSingletonClass instance = new SomeSingletonClass();
     private SomeSingletonClass() {}
 }
Mark Peters