Is it true that every inner class requires an enclosing instance?

回眸只為那壹抹淺笑 提交于 2019-11-28 04:54:59

The distinctions laid out in the question make perfect sense from the specification's standpoint:

  • an inner class has restrictions applied to it, which have nothing to do with the question of enclosing instances (it may not have static members, for example);

  • the concept of a static nested class is basically just about namespacing; these classes might rightfully be termed top-level, together with what we usually assume as top-level classes.

It just so happens that removing static from a nested class declaration does two separate things at once:

  1. it makes the class require an enclosing instance;
  2. it makes the class inner.

We rarely think about inner as entailing restrictions; we only focus on the enclosing instance concern, which is much more visible. However, from the specification's viewpoint, the restrictions are a vital concern.

What we are missing is a term for a class requiring an enclosing instance. There is no such term defined by the JLS, so we have (unaware, it seems) hijacked a related, but in fact essentially different, term to mean that.

Well, doesn't the anonymous class have an enclosing instance in your case as well? It is the reference that's static, not the instance of the anonymous class. Consider:

class A {
   int t() { return 1; }
   static A a = new A() { { System.out.println(t()); } };
}
Mikhail

There is no difference between static inner class and no static. i don't understand why they should be considered separately. Have a look at the following code:

public class Outer {
    public static class StaticInner{
        final Outer parent;

        public StaticInner(Outer parent) {
            this.parent = parent;
        }
    };
    public class Inner{}

    public static void main(String[] args) {
        new StaticInner(new Outer());
        new Outer().new Inner();
    }
}

And then at StaticInner and Inner classes bytecode:

public class so.Outer$Inner extends java.lang.Object{
final so.Outer this$0;
public so.Outer$Inner(so.Outer);
  Code:
   0:   aload_0
   1:   aload_1
   2:   putfield        #1; //Field this$0:Lso/Outer;
   5:   aload_0
   6:   invokespecial   #2; //Method java/lang/Object."<init>":()V
   9:   return

}

public class so.Outer$StaticInner extends java.lang.Object{
final so.Outer parent;
public so.Outer$StaticInner(so.Outer);
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   aload_1
   6:   putfield        #2; //Field parent:Lso/Outer;
   9:   return
}

Actually there is no difference between them at all. I'd say non-static inner class is just a syntactic sugar. A shorter way to write a common thing, no more. The only slight difference is that in no-static inner class, reference to the enclosing class is assigned before calling parent constructor, this might affect some logic, but I don't think that it's so much critical, to consider them separately.

P.S. One more question on a related topic, which might be interesting.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!