现在的位置: 首页 > 综合 > 正文

静态内部类 笔记

2014年02月17日 ⁄ 综合 ⁄ 共 1797字 ⁄ 字号 评论关闭
import java.io.*;
class Instanceof {
	public static void main(String[] args) throws Exception {
		new Instanceof().test();
	}
	public void test() throws Exception{
		System.out.println(new Inner());  //1
		System.out.println(Inner.class.newInstance());  //2
	}
	public class Inner{
		public String toString(){
			return "Innser Object";
		}
	}
}

1处使用new方式来调用内部类的无参构造函数,2处使用反射来调用内部类的无参构造函数
运行时 在2处抛出异常:
Exception in thread "main" java.lang.InstantiationException: Instanceof$Inner
        at java.lang.Class.newInstance0(Class.java:357)
        at java.lang.Class.newInstance(Class.java:325)
        at Instanceof.test(Instanceof.java:40)
        at Instanceof.main(Instanceof.java:33)

都是调用无参构造函数怎么结果不一样呢?

使用javap -c Out.Inner 发现Inner内部类的构造函数有一个Instanceof 参数:

public class Instanceof$Inner {
  final Instanceof this$0;  //①

  public Instanceof$Inner(Instanceof); //②
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1                  // Field this$0:LInstanceof;
       5: aload_0
       6: invokespecial #2                  // Method java/lang/Object."<init>":
()V
       9: return

  public java.lang.String toString();
    Code:
       0: ldc           #3                  // String Innser Object
       2: areturn
}

看到了上面的① ②行就会明白了,其实,内部类的构造函数需要外部类的一个实例对象作为参数。因为非静态内部类是依赖于外部类的,所以需要一个外部类对象!对于1处,在new
Inner时,JVM 把 this 传给了 Inner的构造函数。而对于2处,通过反射技术调用Inner的无参构造函数却没有 外部类对象传给Inner构造函数所以抛出了异常。

class Instanceof extends Out.In {
	public static void main(String[] args)  {
		System.out.println("In Instanceof");	
	}
}
class Out{
	class In{
		public void test(){
			System.out.println("In In test");
		}
	}
	class Child extends In{}
}

上面代码编译错误,提示:
Instanceof.java:4: 错误: 需要包含Out.In的封闭实例
class Instanceof extends Out.In {
^
1 个错误
因为 在子类的构造函数中 会隐式调用父类的无参构造函数,而 Out.In 的无参构造函数其实需要一个Out对象作为参数,所以由于参数的不匹配,提示编译错误。


解决办法

class Instanceof extends Out.In {
	public Instanceof(){
		new Out().super();
	}
	public static void main(String[] args)  {
		System.out.println("In Instanceof");	
	}
}
class Out{
	class In{
		public void test(){
			System.out.println("In In test");
		}
	}
	class Child extends In{}
}

在Instanceof类中写一个构造函数,在第一行 new出以Out对象,以该对象作为主调对象,显式调用Instanceof父类的构造函数即可。这样,就会将new出来的Out 对象传给In的构造函数。








抱歉!评论已关闭.