1.非静态内部类没有无参构造
很简单就可以证明:
public class Outer{
public static void main(String[] args)throws Exception{
new Outer().test();
}
private void test() throws Exception{
System.out.println(new Inner());
System.out.println(Inner.class.newInstance());//反射调用
}
public class Inner{
public String toString(){
return "Inner...";
}
}
}
运行结果:
Inner...
Exception in thread "main" java.lang.InstantiationException: Outer$Inner
at java.lang.Class.newInstance(Class.java:359)
at Outer.test(Outer.java:7)
at Outer.main(Outer.java:3)
我们使用javap工具看下执行过程:
D:\Study Source>javap -c Outer$Inner.class
Compiled from "Outer.java"
public class Outer$Inner {
final Outer this$0;
public Outer$Inner(Outer);//****
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LOuter;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>
9: return
public java.lang.String toString();
Code:
0: ldc #3 // String Inner...
2: areturn
}
可以很明显的在**注释行看出创建Inner类的时候传入了Outer参数,因此当我们使用反射来创建一个类的时候,会去找它的无参构造,而JVM给Inner的default constructer是有一个参数Outer的,而且为什么要传入这个参数呢,因为非静态内部类是依赖于外部类的存在而存在的,所以只有在外部类创建后才能创建内部类,所以必须要保证它的外部类被创建后,它才能创建,因此传入一个外部类参数作为它的默认构造。
2.非静态内部类不能拥有静态变量
这个实际很好解释,静态变量只属于类本身,也称为类变量,也就是在这个类被虚拟机加载的时候就被创建了,而不是在这个类被创建的时候才被创建,我们使用反证法,假如存在这个静态变量,这个静态变量在外部类被加载的时候就创建好了,那么它跟外部类的静态变量又有什么区别了呢?当然从其他角度也能例证这个Java规范。
3.静态内部类不可以访问外部非静态变量
因为静态内部类在外部类被加载的时候已经被创建,而如果静态类访问外部非静态变量的时候,这个非静态变量是在外部变量被创建的时候才被创建和初始化,所以此时会报找不到这个非静态变量。
4.Native方法
public class TestNative{
static{
System.loadLibrary("CppHello");
}
public static void main(String [] args){
new TestNative().info();
}
public native void info();
}
Java类里可以定义一个方法为native方法,没有实现,只声明方法名称类型,与abstract类中的abstract method的形式一样,这个也就是JNI。详见我另外一篇文章具体阐述如何code JNI。