Java嵌套类-底层实现原理?

5

我有几个关于Java中嵌套类的问题。

  • 在内存分配方面,嵌套类是如何出现的?

  • 您不能在嵌套类中声明静态变量(我认为确切的错误是静态属性只能在顶级类中声明)。为什么会这样,嵌套类还有哪些限制?

如果可能,请说明您的答案是针对Java的,还是C++也遵循相同的规则?


2
如果嵌套类本身是static的,那么您可以在嵌套类中声明static变量。 - Jeffrey
3个回答

2
内部类在内存和编译方面与普通类完全相同。 (也许它们在内存中的管理方式有所不同,但对于普通Java开发人员来说是不可见的) 实际上,当您编译具有内部类的类时,您可以将已编译的.class文件视为OuterClass$InnerClass.class。 就我所知,JVM对待它们是相同的。
至于静态变量,我不确定问题是什么。例如,这个对我来说是可运行的:
public class Tester {
  public static void main(String[] args) {
    System.out.println(InnerTester.MY_STRING);
  }

  public class InnerTester {
    public static final String MY_STRING = "MY_STRING";
  }
}

编辑

正如Jeffery所指出的,这段代码无法编译:

public class Tester {
  public static void main(String[] args) {
    System.out.println(InnerTester.MY_STRING);
  }

  public class InnerTester {
    public static String MY_STRING = "MY_STRING";
  }
}

区别在于,我将第一个静态变量列为了final。
经过一段时间的思考,我同意@Eugene的观点。他们允许内部类上的静态字段为final,因为这样就不会有初始化问题。该值不能更改,您只需将其初始化为其值即可。但是,如果静态字段不是final,则需要创建外部类的实例才能初始化该字段,而静态成员无法绑定到特定实例。
我还在这里找到了相关讨论。

4
内部类不允许声明静态成员,除非它们是常量变量(§4.12.4),或者会发生编译时错误。 - Jeffrey

1

基本上,嵌套类只是一个具有引用封闭实例的字段的类。

除非它是静态嵌套类(在其中可以声明静态字段/方法)。 在这种情况下,它只是一个名称中具有另一个路径元素的类(包+封闭类名)。

换句话说,非静态嵌套类(内部类)-不能没有封闭实例存在(例如书中的页面)。您可以按以下方式实例化:

 Book book = ... // a book instance;
 Book.Page page = book.new Page(); // requires an enclosing instance

但是静态嵌套类-完全独立,就像命名空间的问题一样。您可以这样实例化它:

 Outer.NestedStatic instance = new Outer.NestedStatic(); // just name-space

更多信息请参见:http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html


如果是静态类,就像委托,非静态则像组合? - user997112
如果它是非静态的 - 那就是组合。如果它是静态的 - 那只是不同的命名空间 - 完全独立的类。 - Eugene Retunsky
你的术语不正确。内部类是非静态嵌套类,因此不能是静态的。嵌套类可以是静态的。只有内部类具有指向外部实例的指针。 - user207421
@EJP 什么是嵌套和内部的区别? - user997112
1
@user997112 我们可以在方法内声明一个命名类。但是它只能在该方法内部可见(无论它是否有名称)。 - Eugene Retunsky
显示剩余2条评论

0

嵌套类就是在另一个类中定义类型的简单定义。Java不关心新类型在什么范围内定义,您也不需要以任何特殊方式“处理”这个内部类。

如果非静态内部类具有静态字段,则没有意义,因为对非静态内部类的任何引用都必然是实例变量。只有将内部类设置为static,才能静态分配它--在这种情况下,静态内部类是一个独立的类,封闭类名称充当另一个命名空间级别。


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