Question

Today I learnt that you can use the new operator alongside a separator (., or "dot operator"). This made me wonder if Java implicitly uses the same technique for all occurrences of the new operator.

The following statement creates a new "InnerClass object". It does this with a new ParentClass object, using .new. However, the first new operator in this statement isn't preceded by a constructor (or an object). So, does Java add one in at compile time? I tried explicitly adding one (Main()) in to this statement, but the code wouldn't compile.

ParentClass.InnerClass ic = new ParentClass().new InnerClass();
Was it helpful?

Solution

The form

someObject.new InnerClass()

is only used for inner classes. Instances of an inner class must be associated with an instance of their enclosing class. Often, the enclosing instance is this, negating the need for dotted notation, but when you want to explicitly create an instance of an inner class associated with a different object, the above syntax is what you use.

Most classes in Java are not inner classes. There is no need for an enclosing instance, and thus Java does not implicitly insert new Something() before all new calls. (If it did, it would have to insert new Something() before the calls it inserted, and new Something() before those, and you couldn't construct anything at all.)

OTHER TIPS

Outer classes and static inner classes can be created on their own, without any parent elements. Non-static inner classes though need to be part of a parent element. Because the concept of a parent element doesn't exist for outer and static classes there is no possibility to have a reference to that parent.

This form is provided to allow you to construct the outer and inner object in one step and just keep the reference to the inner one. I've never found much use for it but it's handy to know that it exists.

I haven't looked at the internals of this but let's first assume the compiler adds an object to proceed new at compile time. That would mean that all our classes are inner classes to another class. Since they are not declared within another class this is not the case. So: no, it does not add something like this at compile time.

Actually, let's break this down.

public class Outer {

    String strHello = "Hello ^^";

    public void printHello() {
        System.out.println(strHello);
    }

    public static void main(String[] args) {

        // This will print: Hello ^^
        Outer outer = new Outer();
        outer.printHello();

        // This will print: Hello ^^
        new Outer().printHello();
    }
}

I'm guessing you've seen code like this before. It's simply calling a method of the instantiated class. The dot notation can also be used to access variables and inner classes. In the above we have used it to an instance method. Using the keyword static allows methods and variables to be shared will all instances of the class or even separate classes.

public class Outer {

    static String strHello = "Hello ^^";

    public static void printHello() {
        System.out.println(strHello);
    }

    static class StaticInner {
    }

    static class Inner {
    }

    public static void main(String[] args) {

        // Prints: Hello ^^
        Outer.printHello();

        // Constructs a new Example.StaticInner
        Outer.StaticInner inner = new Outer.StaticInner();

        // Constructs a new Outer.Inner     
        Outer.Inner inner = new Example().new Inner();

        // Constructs a new Outer.Inner
        Example ex = new Example();
        Outer.Inner inner = ex.new Inner();
    }
}

The above code uses a static inner class to hopefully demonstrate that an inner constructor is just like any other constructor. But, because it's within another class we need to access it through the other (outer) class. It it's not a static inner class then we need to use an instance to access it due to the access modifiers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top