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

理解Java内部类

2016-07-06 15:41 225 查看
        内部类分为成员内部类、局部内部类、静态内部类和匿名内部类。  

           成员内部类就是像类成员变量一样定义一个class, 作用域是外部类内; 局部内部类定义在函数里, 作用域就在函数内, 类似于局部变量; 静态内部类就是添加static关键字,   静态类内部不能访问外部类的非静态变量了。

        这里有个知识点, 内部类里为什么能够得到外部类成员变量的值? 因为内部类持有外部类的引用, 具体参见http://www.tuicool.com/articles/Nj2qUz7

         我觉得比较难理解的是匿名内部类,  它的表现方式是new ...{}, 典型场景就是按钮点击回调或其它各种回调。 我觉得比较难理解的是为什么叫匿名。 其实看看编译生成的.class文件就明白了,  它是按照$1,$2,$3等等方式命名的。

  


     如上图所示BaseActivity$MyOnNetChangeListener.class中MyOnNetChangedListener.class就是成员内部类。   没真正名字用1/2/3等等命名的就是匿名内部类了, 如DifferentMenuActivity$1.class。

       外部类可以访问非静态内部类的私有成员和方法, 内部类也可以访问外部类的私有成员和方法。

public class TestInner {
private String name;
Inner instance;
TestInner() {
instance = new Inner();
}
class Inner {
public Inner() {
value = 0;
}
private int value;
public void showLog() {
System.out.print(name);   //访问外部类的私有变量
}
}

public int getValue() {
return instance.value; //访问内部类的私有变量
}

public void setValue(int value) {
instance.value = value;
}
}


       为什么内部类可以访问外部类的私有成员? 因为内部类持有外部类的引用!   执行javap -p -v TestInner$Inner.class反编译出字节码, 可以看出编译器自动添加了一个构造函数,并传入外部类的引用。



     为什么外部类可以访问内部类的私有成员? 因为编译器会自动生成access$100方法!

反编译.class文件,可以看到getValue方法里调用access$100方法。



       使用反射也可以看到TestInner类方法数是3, 多个一个access$000方法, 这是因为函数体访问了内部类的私有变量。


 

  匿名内部类访问外部变量时必须添加final关键字, 以下面代码为例。 Runnable内部类中total参数实际是外部类total的拷贝。 如果外部类修改该外部类参数, 内部类中对应的拷贝不会随之改变, 从而可能出现数据不一致问题。 为了避免这个问题, Java语法规定要用final关键字声明为常量。

final int total = 100;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(total); //实际是外部变量total的一个拷贝
}
}).start();

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