您的位置:首页 > 编程语言 > Java开发

Java内部类(inner Class)和嵌套类(static inner Class)也就是静态内部类的区别

2017-11-07 09:11 477 查看
内部类和静态类有着本质的区别,有点类似普通成员变量和静态成员变量的区别

.

内部类可以看成是外部类的普通成员变量,这个成员变量可以使用外部类的属性(静态和非静态),可以调用外部类的方法(静态和非静态),而且内部类还持有外部类对象作为其自身的一个属性,这个属性的名称叫 this$0,可以使用反射获取外部类对象。内部类对象在其他类中不能使用构造函数直接new得到,因为内部类对象类似外部类的成员变量,外部类不存在时,内部属性自然不能生成。内部类持有外部类对象的最好实例就是容器类的Iterator对象,通过容器类的iterator()方法得到Iterator对象,然后通过Iterator对象就能遍历容器,就是因为Iterator对象持有外部对象也就是容器对象的实例,大部分容器均有一个内部类实现了Iterator接口,实现自己的遍历逻辑。

.

嵌套类可以看成是外部类的静态成员,只能使用外部类的静态属性和静态方法。嵌套类是独立于外部类存在的,也就是其他类可以通过调用嵌套类的构造函数来获取嵌套类实例。嵌套类不持有外部类对象实例,嵌套类可以看成是另外一个独立的类。很多情况是嵌套类仅仅在外部类里使用,使用嵌套类对外部类的几个属性或者一些函数做一个封装,便于外部类的逻辑实现 , 所以其修饰符很多时候定义为private static class。

.

内部类和嵌套类的类名均是:外部类名称+$+自身类名称,比如com.bob.test.concrete.clazz.TopLevelClass$NestedClass,com.bob.test.concrete.clazz.TopLevelClass$InnerClass,包名和外部类一致。

可以通过外部类的Class.getDeclaredClasses()方法获取所有定义的内部类和嵌套类。

代码示例:

public class TopLevelClass {

private int id;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public InnerClass getInnerClass(){
return new InnerClass();
}

public NestedClass getNestedClass(){
return new NestedClass();
}

public static void print(){
System.out.println("调用静态方法");
}

/**
* 内部类
*/
public class InnerClass {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String toString(){
//内部类可以使用外部类的属性和方法
return id + name;
}
}

/**
* 嵌套类,静态内部类
*/
public static class NestedClass {

private int age;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void print(){
//嵌套类智能使用外部类的静态成员及方法
TopLevelClass.print();
}
}

}


代码测试:

public class InnerClassTest {

@Test
public void getInnerClass(){
//InnerClass is = new InnerClass(); 会报错
InnerClass is = new TopLevelClass().getInnerClass();
}

@Test
public void getNestedClass(){
NestedClass ns = new NestedClass();
ns = new TopLevelClass().getNestedClass();
}

@Test
public void testInnerClassName() {
//获取所有的内部类及嵌套类
Class<?>[] classes = TopLevelClass.class.getDeclaredClasses();
for (Class<?> clazz : classes) {
//内部类和嵌套类都属于成员类
System.out.println(clazz.isMemberClass());
System.out.println(
"Class.Name = " + clazz.getName() + ", Class.SimpleName = " + clazz.getSimpleName() + ", Class.Package = " + clazz.getPackage().getName());
}
System.out.println(TopLevelClass.class.isMemberClass());
}

@Test
public void getOutterClassInstance() throws NoSuchFieldException, IllegalAccessException {
TopLevelClass tps = new TopLevelClass();
InnerClass is = tps.getInnerClass();
Field filed = is.getClass().getDeclaredField("this$0");
//获取内部类对象持有的外部类实例
TopLevelClass innerTps = (TopLevelClass)filed.get(is);
//返回true,他们是同一个对象
System.out.println(tps == innerTps);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jdk