现在的位置: 首页 > 编程技术 > Java > 正文

Java学习-嵌套类 vs 内部类

2015年11月26日 Java ⁄ 共 1515字 ⁄ 字号 Java学习-嵌套类 vs 内部类已关闭评论 ⁄ 阅读 952 次
  • 顶层类 - top-level class
  • 嵌套类 - nested class
  • 内部类 - inner class(aka: non-static nested class)
  • 外围类 - outer class(aka: enclosing class)

首先通过Java Language Specs的一段话来详细看一下内部类,嵌套类的关系
> A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.Static nested classes do not have access to other members of the enclosing class.

根据这段话我们可以看出,嵌套类分为两种
1. 一种是静态嵌套类(static nested class),对外围类无法直接访问,可以直接使用类名实例化 2. 一种是非静态嵌套类(inner class), 对外围类也可以直接访问,甚至是私有属性,方法或者构造函数, 但必须依附外部类实例才能实例化

静态嵌套类有什么特别之处吗?
再来看一句话

A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

可以看出,静态嵌套类,与顶层一般类没有太多区别,按原话的意思,仅仅是方便进行包的管理。 再说一句就是从oop设计的角度上,类的结构条理清晰。

jdk里LinkedList中的实现,把节点定义成 private static class Node<E>
首先有了private修饰,不可能在外部使用。
但考虑到是泛型, 封装的因素,所以定义成了内部类。我估计设计者是因为不想在util库里莫名其妙的多一个类来,因为该类只有linkedlist使用。 然后至于为何定义成静态的,我有一点疑惑,考虑到静态非静态的区别,在本类的使用上其实没有影响。因为即便是非静态的定义,在节点定义的时候外部链表类也早已实例化。

看到一句话: > 内部类是Java编译器一手操办的。虚拟机并不知道内部类与常规类有什么不同。

首先实例化的节点对象都是在堆内存,而不一样的是方法区中加载类的类型信息,以及栈上的对象引用。 内部类编译后也是一个单独的类。当内部类被使用时,才会被加载。 内存使用上,类型信息的存储,以及引用的存储,不会耗费太多内存空间。然后堆上的分配都是按需所取。

有意思的一点是:
如果私有内部类没有显示声明构造函数,编译后会生成一个{内部类类名$1.class}的文件
这个通过反编译可以看到是一个空类,产生一个包可见构造函数,格式如下:
{外部类类名$内部类类名(外部类类名, 外部类类名$1);}
这个构造函数可以确保内部类的private特性: 不能从外部其他类实例化。
只有在外部类明确分配内部类的内存时,才会产生这个构造函数。仅仅声明引用的话,不会生成这个构造函数。同样,针对外部类的private变量,如果在内部类中明确使用了,才会在外部类编译时加上一个static的访问函数:static int access$100();

抱歉!评论已关闭.