为什么Java不允许创建内部类的实例?

3
我有一个主类“m”,还有两个内部类称为sub1和sub2,其中sub2是静态类。
public class m
{
  String n="n";
  static String s="s";
  public class sub1
  {
    public void fn(){System.out.println(n);}
    //static public void fs(){System.out.println(s);}
  }
  static class sub2
  {
    //public void fn(){System.out.println(n);}
    static public void fs(){System.out.println(s);}
  }
  public void f()
  {
    sub1 s1=new sub1();//OK, no error
    sub2 s2=new sub2();//OK
  }

  public static void main(String[] args)
  {
    m obj=new m();
    sub1 s1=new sub1();//Error
    s1.fn();
    //s1.fs();
    sub2 s2=new sub2();//OK
    //s2.fn();
    s2.fs();
  }
}

我使用Openjdk在Linux下编译它,但报错了。

$ java -version
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~16.04.1-b14)
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

$ javac m.java 
m.java:24: Error: Cannot reference non-static variable this in a static context.
    sub1 s1=new sub1();//Error
            ^
1 Errors

这对我来说很奇怪: 1. 在m.f()成员函数中,我们可以使用"sub1 s1=new sub1();",但在main函数中,我们不能 2. 静态类sub2可以有实例,而非静态的sub1却不行?

这是Java的设计吗?为什么?

1个回答

7
  • 非静态的内部类被视为外部类的成员。
  • 要创建它们的实例,需要使用外部类的引用。

因此,您需要像这样做:

OuterClass outer = new OuterClass();
InnerClass inner = outer.new InnerClass();

所以,在你的情况下,
m obj = new m();
sub1 s1 = obj.new Sub1();

内部类被视为外部类的成员变量。这是什么意思?内部类不是外部类的成员变量。它们被视为成员变量的方式是什么? 内部类作为外部类的成员变量对待,意味着内部类具有与外部类成员变量相似的访问权限和生命周期。可以使用内部类来实现一些功能,而无需暴露给外部世界。 - Erwin Bolwidt
也许我写的话有点混淆。我的意思是它们作为外部类的成员,因此需要使用外部类引用进行访问。我从Kathie Sierra的SCJP书籍中学习了这一点,第8章讲解了内部类。 - Prasad Kharkar
非静态内部类被视为外部类的成员。但是,静态成员类也是外部类的成员。JLS:“成员类是直接包含在另一个类或接口声明中的类。”内部类的特殊之处在于它们具有封闭实例。 - Erwin Bolwidt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接