5

I have the following java classes:

public class Outer { ... private class Inner { ... } ... } 

Assume I am inside a non-static method of Outer. Does it make a difference whether I call this.new Inner() or new Outer.Inner()? Is it, in the second case, guaranteed that no new Outer is created?

I have an annoying error in my program that appears only sometimes and is hard to find or to reproduce. So I am wondering if this line could make any problems.

8
  • If you declare an inner class it's basically because you won't use it anywhere else. But they still being different classes. If you instance an object of outer u wont need to declare an inner. Commented Dec 15, 2020 at 8:17
  • to avoid this this.new Inner() or new Outer.Inner(), you can declare your inner class as static class. private static class Inner Commented Dec 15, 2020 at 8:20
  • 8
    I believe the two constructor invocations you posted are functionally identical (it would be a different matter if you had written new Outer().new Inner(). But wouldn't it be more helpful for your search to post the error you are trying to resolve? Commented Dec 15, 2020 at 8:20
  • Thank you, that was the main question whether these two lines are semantically identical. But I think that is a question of knowing the Java standard and not "believing", isn't it? :-) Commented Dec 15, 2020 at 8:26
  • 1
    You can ask yourself: how would it even theoretically be able to create another Outer instance? Since you do not specify its constructor parameter it is not possible that a custom constructor will be invoked and therefore not possible another Outer is created. Commented Dec 15, 2020 at 8:39

1 Answer 1

7

They are the same, though they are both unnecessarily long-winded.

The following 3 versions results in the exact same bytecode:

class Outer { private class Inner { } void foo() { Inner a = this.new Inner(); Inner b = new Outer.Inner(); Inner c = new Inner(); // Recommended way to write it } } 

Bytecode

 0: new #7 // class Outer$Inner 3: dup 4: aload_0 5: invokespecial #9 // Method Outer$Inner."<init>":(LOuter;)V 8: astore_1 9: new #7 // class Outer$Inner 12: dup 13: aload_0 14: invokespecial #9 // Method Outer$Inner."<init>":(LOuter;)V 17: astore_2 18: new #7 // class Outer$Inner 21: dup 22: aload_0 23: invokespecial #9 // Method Outer$Inner."<init>":(LOuter;)V 26: astore_3 

Blank lines added to improve clarity.

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

2 Comments

new Outer.Inner(); is sometimes usefull when instantiating an inner public static class from somewhere else. I think of it like an additional package / scope qualifier.
@RetoHöhener It is good that you think that, because that's exactly what it is. Similarly, this.new Inner(), or rather other.new Inner(), is useful when you want the Inner object to be linked to an Outer object other than this, which is similar to how you can access a field using name or this.name, you can write new Inner() or this.new Inner(), makes no difference.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.