3

When i initialize the static inner class i am expecting that outer class is also initialized and will print I should see this as well. however this is not happening and i am getting only class Main as a output

 class AA {
    static {
        System.out.println("I should see this as well.");
    }

    public static class BB {
        BB() {
            Object o = Main.class; 
            System.out.println(o.toString());
        }
    };
}

public class Test {
    public static void main(String[] args) {
        new AA.BB();
    }
}

Can some one help me , explaining this behavior.

13
  • Static inner classes are not as closely related to their outer classes as non-static ones. In fact you can see the outer class of static inner classes as some kind of namespace (or package). Commented May 5, 2017 at 9:11
  • 3
    A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience. source Commented May 5, 2017 at 9:11
  • Once they're compiled, they're sufficiently separated that you can load one class without the other. Commented May 5, 2017 at 9:17
  • 1
    One of those questions that make your head spin for a second ;-) ... funny thing. Have my vote for that! Commented May 5, 2017 at 9:18
  • 1
    Wow - so AA and AA.BB implemented as different classes? Never thought of that! Commented May 5, 2017 at 9:29

2 Answers 2

3

Thing is: that static initializer block gets executed lazily. Meaning: this code gets executed the first time that the AA class is really "required". But AA is not required to instantiate AA$BB.

If you change

BB() {
  Object o = Main.class; 
  System.out.println(o.toString());
}

to really require class AA to be loaded:

BB() {
  Object o = Main.class; 
  System.out.println(o.toString());
  new AA();
}

then that other string gets printed, too.

Keep in mind: it is only within your source code that BB is "inside" AA. From a class loader point of view, AA and BB are (somehow) two independent classes coming from two different class files!

Edit, given the question "how to see" that:

A) I replaced Main.class with Test.class and compiled, and I find in my file system AA$BB.class AA.class Test.class afterwards.

B) now you can run [javap][1] -c "AA$BB.class" to see more about the content of that class

Sign up to request clarification or add additional context in comments.

2 Comments

You are right when you say "From a class loader point of view, AA and BB are (somehow) two independent classes coming from two different class files!"--- I want to check this behavior any tool or other way you recommend to see this behavior.
@Show Stopper, ??? Your question includes code that shows this behavior already! It's the basis of your question, that it shows the behavior!
3

A nested class creates a distinct class.

Here you would have two classes :

  • AA.class

  • AA$BB.class

Using the second one doesn't require to load the first one as the second is a public static class.

5 Comments

There's no inner class in the question.
BB is static. It therefore is not an inner class. Read the Fine Manual at docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3.
"An inner class is a nested class that is not explicitly or implicitly declared static."
@Lew Bloch You learn me something. To complete : "Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.". I edit consequently.
You haven't edited your answer to remove the incorrect reference to "inner class".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.