0

I'm a little bit confuse. While reading java tutorial a question "wake up" for me. If i decided that the nested class need to be with private access modifier, does it matter (at all) if the nested class will be static or not? Initially i thought it doesn't matter but after writing some classes in order to verify my intuition i found some different "results" when running the program with and without the "static" keyword.

Following code doesn't compile, get the following compilation error: "non static method callByInnerClass() cannot be referenced from a static context"

public class Outer
{
    private String outerString = "nnnn";
    private InnerStatic iS;
    public void createInnerClassInstance()
    {
        iS = new InnerStatic("innter"); 
    }


    public void runInnerMethod()
    {
        iS.callInnerMethod();
    }

    // if method runs it mean the inner static class can run outer methods

    public String calledByInnerClass()
    {
        System.out.println("Inner class can call Outer class non static method");
        System.out.println("nn value after ruuning inner class is: " +outerString );
    }

    public static class InnerStatic
    {
        public String innerString;

        public InnerStatic(String str)
        {
            innerString = str;
        }

        public void callInnerMethod()
        {
            System.out.println(innerString);
            outerString  = "aaa";
            calledByInnerClass();
        }

    }
}

When removing "static" keyword before inner class, then program is compiled successfully. What is the reason that when "static" keyword exist, than the nested class can't find his outer class instance (and considered inner)? I read that when creating from different class an object of inner class, then inner class automatically has outer class instance, but this situation feels a little bit different

Eitanos30
  • 1,331
  • 11
  • 19
  • 2
    Yes, it matters. If the nested class isn't static, it needs an instance of the containing class present to be created. It also affects variable scope/visibility – Hovercraft Full Of Eels Oct 19 '19 at 14:06
  • Lets start with basics. Are you familiar with what `static` keyword means in Java? What difference does it make for members like fields and methods to be made static vs non-static? – Pshemo Oct 19 '19 at 14:37
  • @Pshemo,yes i am. Static keywork mean that variables/methods belongs to class and not to instance of class – Eitanos30 Oct 19 '19 at 15:17
  • 1
    Yes, in other words in `static` method there is no `this` (which refers to instance *on which method is invoked*) but it exists within non-static methods which allows us to write code like `void foo(){ this.bar(); }` or even `void foo(){ bar(); }` (here `this.` before `bar()` will be generated by compiler). Similarly static and non-static nested types differ, but in their case non-static nested class have `this$0` hidden variable which holds reference to outer class *instance* on which non-static class was created and when we write `outerMethod()` compiler will generate `this$0.outerMethod()`. – Pshemo Oct 19 '19 at 15:51
  • 1
    Instances of static nested classes are not created *via* outer instances like `outerClassInstance.new StaticNestedClass();` so they don't have such `this$0` which means compiler will not be able to change within them `nonStaticOuterMethod()` into `this$0.nonStaticOuterMethod()`. More info: [What does it mean if a variable has the name “this$0” in IntelliJ IDEA while debugging Java?](https://stackoverflow.com/q/28462849). – Pshemo Oct 19 '19 at 15:55
  • @Pshemo, 'this$0' helped me understanding thins much better. But in the code i have published, nested class is created inside outer class code (in function createInnerClassInstance) and not from an outside class. So i thought it's "enough" for compiler to make the connection (set this$0 reference with the outer class instance) while creating static nested class, because it's "clear" for him who is the outer class – Eitanos30 Oct 19 '19 at 16:03
  • "*So i thought it's "enough" for compiler to make the connection (set this$0 reference...*" problem her is that your `InnerStatic` is `static`, so it doesn't have `this$0` to begin with. BTW *inner* type is by definition non-static. Nested classes can be static and non-static, but when nested class is declared as non-static it can be named as *inner* class. To avoid confusion it is safer to call them *nested* if you are not sure if they will be static nor non-static. – Pshemo Oct 19 '19 at 16:19
  • @Pshemo, '_problem her is that your InnerStatic is static, so it doesn't have this$0 to begin with_'. This sentence what the closure for you great explanation above.Maybe you should post it as a response and not as a comment, so other will be able to "earn" from it too – Eitanos30 Oct 19 '19 at 16:26
  • @Eitanos30 Honestly I am not sure if anyone will be able to see it even if I post it as an answer since it has very little to do with your question. This is more about difference between static vs non-static than private static vs private non-static (which question title is about). – Pshemo Oct 19 '19 at 17:16
  • @Pshemo, if it will help you i can elaborate the question a little bit. Any case, thank you – Eitanos30 Oct 19 '19 at 17:25
  • Well, we already have similar question: [Java inner class and static nested class](https://stackoverflow.com/q/70324) and it has an answer which covers `this$0`. Would you mind if I mark your question as duplicate of that one? – Pshemo Oct 19 '19 at 17:31
  • If it won't harm my reputation, i think it's ok. – Eitanos30 Oct 20 '19 at 14:39

1 Answers1

0

You cannot access your non-static calledByInnerClass method from static class. That is why it gives an error. To do so, you need either make calledByInnerClass static or your inner class non-static

Marat
  • 1,288
  • 2
  • 11
  • 22