Home » Java » java – Creating an instance from another instance?-Exceptionshub

java – Creating an instance from another instance?-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I’m so confused that how could it be written like this… It creates an instance from another instance

st.new FirstLevel();

    public class ShadowTest {

    public int x = 0;



    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);
            System.out.println("this.x = " + this.x);
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);

        ShadowTest.FirstLevel mali = st.new FirstLevel();           
    }
}
How to&Answers:

Here, FirstLevel is a so-called inner class – that’s because it is defined inside another class. Both relations (the ‘outer’ and the ‘inner’) are plain jane classes (and not interfaces, enums, or records). In this case, unless the inner class has the modifier static on it (and, in your code, it doesn’t), then you get an instance inner class.

Such classes have a hidden field of the outer type associated with them. It is as if your FirstLevel class has this field:

private final ShadowTest outerInstance;

And each and every constructor of ShadowTest has a parameter for this field, but, it is hidden and a bit special.

Because this secret field exists, you can do things like invoke non-static methods from ShadowTest from within FirstLevel.

If you type new FirstLevel(), that just works… but only within non-static contexts inside ShadowTest. Anywhere else and the compiler will tell you that it doesn’t know what instance of ShadowTest to pass along for that secret field. You can explicitly define which instance of ShadowTest. But not with new FirstLevel(shadowTestInstance), but with the somewhat weird-looking syntax shadowTestInstance.new FirstLevel(). But, it’s the same thing: A parameter being passed to a constructor.

I generally advise that you do not use instance inner classes unless you really know they are the best fit for the case; this hidden field tends to cause confusion and surprises. I’d go so far as to say that you should never have instance inner classes; if you must hold a reference to an instance of the outer class, make it explicit (add an actual field, and make an actual parameter in your constructor). That way you avoid the surprises and confusion, at least. In other words, mark your FirstLevel class as static. By making your outer reference explicit, the shadowing thing also goes away; now you just have x or this.x referring to the x field in FirstLevel, and outerInstance.x for the outer field:

static class FirstLevel {
    final ShadowTest shadow;
    int x;

    public FirstLevel(ShadowTest shadow) { this.shadow = shadow; }
}

Answer:

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object’s methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.ref.javaOO_nested

As per java syntaxes, unless it’s a private or static class you could initialize it in the following way

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

Then a sample initialisation can be done so:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

NOTE: I have referred the block to the oracle java docs. You can read more there