内部类是java里面一种比较特殊的类。在类里面创建类。
package codeTest; public class Outer { int out_a = 1; private class inner{ private int inner_a = out_a; } // int out_b = inner_a; /** * @param args */ public static void main(String[] args) { Outer o = new Outer(); Outer.inner i = o.new inner(); int j = i.inner_a; // TODO Auto-generated method stub } }
访问内部类,用外部类.new 内部类构造函数的方法访问。以上代码没有报错,说明在内部类里可以随意访问外部类的成员,在外部类的实例化内部类,也可以访问内部类的所有成员,包括private成员。
查看编译后的文件,发现内部类被编译成Outer$inner.class,用反编译工具查看该class文件,结果如下:
package codeTest; class Outer$inner { private int inner_a; private Outer$inner(Outer paramOuter) { this.inner_a = paramOuter.out_a; } }
说明jvm在编译内部类的时候,会默认创建一个以外部类对象为参数的构造函数。修改内部类构造函数
class inner { public inner(int i) { } public inner(int... i) { } public inner(int i,String s) { } public inner(int i,String s,Outer o) { } public int inttest(){ int i = out_a; return i; } }
反编译内部类的class:
package codeTest; class Outer$inner { public Outer$inner(Outer paramOuter, int i) { } public Outer$inner(Outer paramOuter, int[] i) { } public Outer$inner(Outer paramOuter, int i, String s) { } public Outer$inner(Outer paramOuter1, int i, String s, Outer o) { } public int inttest() { int i = this.this$0.out_a; return i; } }
说明不管你的内部类的构造函数用什么样的参数,他都会在参数列表里新加一个外部类。这就很好的说明了为什么内部类可以访问外部类的成员:在构造函数里就将外部类的成员初始化进内部类中。
我做项目以来,碰到的最多的内部类是匿名内部类。碰到最多的是list自定义排序和新建线程:
public static void main(String[] args) { List<Integer> l = Arrays.asList(1,8,4,14,25,5,88,2); Collections.sort(l, new Comparator<Integer>(){ @Override public int compare(Integer o1, Integer o2) { // TODO Auto-generated method stub return o1 - o2; } }); System.out.println(Arrays.toString(l.toArray())); }
结果:
[1, 2, 4, 5, 8, 14, 25, 88]
线程:
public static void main(String[] args) { new Thread(){ public void run(){ System.out.println("My Thread"); } }.start(); }
结果:
My Thread
至于其他情况,为什么要使用内部类,thinking in java 上和网上的答案大多是为了隐藏具体实现,和为了能够实现对类的多继承。目前为止我没发现有这方面的需求,可能是自己写的程序太少了,先mark一下, 如果以后有用到这方面的东西再回来修改博客。