4

If we have a code...

public class Hello
{
    public static void main(String args[])
    {
        Outer obj=new Outer();
        obj.method1();
    }
}

class Outer
{
    void method1()
    {
        class Inner
        {
        }
    }
}

I wanted to know,when the Inner class will be loaded by the ClassLoader. Is it loaded at the time the method1() is called,or at the time when we will be creating its instance?And the class Inner is not performing any operation in method1(),its an empty class.Also,I wanted to know,how to create an instance of inner class in the above example?

Frosted Cupcake
  • 1,909
  • 2
  • 20
  • 42

3 Answers3

2

Class Outer.Inner will be loaded the first time another class that refers to it as a variable type, method parameter type, method return type, superclass type, type parameter bound, or target type of an initializer or static method, or host class of a static variable reference is loaded. In your example, I would expect it never to be loaded.

Also,I wanted to know,how to create an instance of inner class in the above example?

As it is written, class Outer.Inner is accessible only inside method Outer.method1(), therefore it can be instantiated only within that method. There, you can just use new Inner(). If you want it to be instantiable from elsewhere then move its declaration out of the method body:

class Outer
{
    class Inner
    {
    }

    void method1()
    {
    }
}

That's better form for a named inner class anyway. It will not change when or whether Outer.Inner is loaded.

With that change, you can instantiate Outer.Inner anywhere within a constructor or instance method of Outer via the form new Inner(). If, however, you want to instantiate one from a different class, or in a static method of class Outer, then it's a bit trickier. The important thing to realize is that each instance of Outer.Inner needs an associated instance of Outer. This is determined from context when the instantiation is performed in an instance method of Outer, but if it is performed without such a context then the syntax is:

    public static void main(String args[])
    {
        Outer obj=new Outer();
        Outer.Inner inner = obj.new Outer.Inner();
    }
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
1

Quoting from Section 12.4.1 of the JLS :

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

T is a class and an instance of T is created.

A static method declared by T is invoked.

A static field declared by T is assigned.

A static field declared by T is used and the field is not a constant variable (§4.12.4).

T is a top level class (§7.6) and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

Therefore, a class (regardless of whether is a nested class) will follow the same rules. In your particular case, Inner will not be loaded until an instance of the class is created.

To answer your second question, you can only create an instance of Inner inside method1 since Inner is a method local class whose scope is limited to method1 :

void method1()
{

    class Inner
    {
        public Inner()
        {
            System.out.println("inner()");
        }
    }

    Inner inner = new Inner();
}
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
0

To achieve the inner class, you need object anyway. If you call method1() like this, inner class never be called.

But if you define some object in method1() or public Outer() constructor, you can get result from inner class.

stuck
  • 1,477
  • 2
  • 14
  • 30