看Concurrent包源码时,其中存在大量的内部类使用,所以特地抽出一篇来介绍内部类。内部类其实是Java 经常用到的一个小的知识点。
内部类:
在一个类内部定义的类叫做内部类,根据内部类在外部类中存在的位置、使用方式、修饰方式可以简单的分为 普通内部类、静态内部类、局部内部类、匿名内部类。
成员内部类:(普通内部类)
1、在一个类内部定义,属于外部类的一个成员类,存在访问属性,无static修饰。
2、同其他成员,内部类可以无限制的访问外部类的其他成员。
3、依赖于外部类对象创建。
4、编译后class文件的样子OuterClass.class和OuterClass$InnerClass.class
常见问题:
1、普通内部类中不能存在任何static的变量和方法。
(原因:依赖外部类对象创建及使用,static类型的属性和方法,在类加载的时候就会存在于内存中。要使用某个类的static属性或者方法,那么这个类必须要加载到jvm中。如果可以用,可能会存在这样一种情况:内部类未加载,但是却试图在内存中创建static的属性和方法,这当然是错误的。原因:类还不存在,但却希望操作它的属性和方法。)
2、成员隐藏:当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要 外部类.this.成员变量 这样访问。
局部内部类:
1、定义在作用域或方法内部的类。
2、尽在作用域内有效,无访问属性
匿名内部类:
这个在使用tunable、callable的时候非常多,很适合用于触发事件,如果是想做安卓客户端的程序员,这种方式将会非常常见。
1、匿名内部类,无名字、无构造函数。
2、无访问修饰符
常见问题:
匿名内部类形参是final的,因为匿名内部类使用外部变量的时候,是通过copy来实现的,当你对参数进行改变时其实改变的是复制之后的值,并不会产生什么效果。为了避免产生什么奇异,索性就final吧,就别变了。
静态内部类:
1、存在于类中,有 static进行修饰。
2、创建是不需要依赖于外部类,不能使用任何外部类非静态属性。
第二点很好理解,不依赖于外部类,也就是创建时并不依赖于外部类对象进行创建,那非静态属性,是对象所持有的,所以说如果能访问,则产生了矛盾。