17

I would like to know if you have a class with only static methods in it, does an actual instance of the class get created somewhere when you call 1st static method?

This is somewhat confusing to understand in terms of memory management as you never actually call the constructor or create an instance of the method explicitly.

If an instance does get created, I would like to better understand where this instance lives and for how long.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
AlexVPerl
  • 7,652
  • 8
  • 51
  • 83
  • 6
    You're confusing class loading (which creates `Class` objects and various VM-specific metadata) with object instantiation. (Note that abstract classes can have static methods -- no hidden automagic instantiation would be possible.) – Jeffrey Bosboom May 27 '15 at 01:46

3 Answers3

13

No. Calling a static method does not require (or create) an instance of a class. See also JLS-8.4.3.2 static methods which says (in part)

A method that is declared static is called a class method.

...

A class method is always invoked without reference to a particular object.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 2
    Thank you this helps. A parallel question, lets say you create an anonymous class inside a static method, what happens to the parent reference that is assigned to the anonymous class (as in java anonymous and inner classes by default get a strong reference back to enclosing object)? – AlexVPerl May 27 '15 at 01:51
  • 2
    I assume you mean a [JLS-15.9.5](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5) Anonymous Class. The JLS says (in part) *an anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1).* Regardless, at the end of the method invocation it goes out of scope (unless it's assigned to a different, `static`, reference). – Elliott Frisch May 27 '15 at 01:54
  • 3
    @AlexVPerl there is no enclosing object, and anonymous classes in static methods have no parent reference. – Louis Wasserman May 27 '15 at 02:19
  • 1
    It might be helpful to mention that it does not require an instance of that class, but it does require an instance of java.lang.Class that represents the class that contains the method. The Class instance instantiation and garbage collection is handled by the JVM via ClassLoaders. – LordOfThePigs May 27 '15 at 11:13
7

Say you have

static class Foo
{
    static Bar bar = new Bar();

    static int func(){ ... }
}

obviously, a Foo object will not be created for calling func().

However, the class Foo needs to be loaded in memory; and to the application, there is an object corresponding to the class, which can be referred to as Foo.class, or Class.forName("Foo").

A loaded class is not initialized yet. When you call a static method for the 1st time, the class is initialized; some "space" is allocated for static variables, and static initializer code (like new Bar()) is executed.

This "space" is not visible to application as an object; but it's an in memory data structure too that concerns garbage collections (and other objects it refers to, like bar)

The class, and the "space", are only eligible for GC when the classloader that loaded the class is eligible for GC. For usual command line applications, that never happens. But for a lot of other applications, class GC is important, and class loading needs to be carefully done.

ZhongYu
  • 19,446
  • 5
  • 33
  • 61
  • 2
    Unless it's changed in Java 8, "static class" doesn't make sense in Java unless it's a nested class. – George T May 27 '15 at 07:28
4

static methods belong to the class, not to the object reference. You can call static method and forget about wasting memory on creating an object reference of the class being used, that doesn't happen. When you call an static method on an object reference, you get a compiler warning on the subject. You can even call static methods on a variable of the desired class and this variable can be null, the static method will be invoked with no problem.

public class Foo {
    public static void sayHello(String name) {
        System.out.println("Hello " + name);
    }
}

//works, no instance of Foo was created
Foo.sayHello("AlexVPerl");
Foo foo = new Foo();
//works, compiler raises a warning here
foo.sayHello("AlexVPerl");
foo = null;
//works, compiler raises a warning here
//and as you can see, it doesn't matter if the instance is null
foo.sayHello("AlexVPerl"); 
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332