成员内部类
拥有四种访问修饰符public、protected、default、private,会限制外部对内部类的创建
// 如果将内部类的访问方式定义为protected
public class OuterClass {
protected class InnerClass{
/**
* InnerClass这个内部类是protected修饰的,如果一个类没有定义任何构造函数,Java编译器会默认的给类生成一个空参数构造函数,
* 而这个构造函数的访问级别是和类访问级别相同的,所以产生了报错,因为OuterClass并不是InnerClass的子类且不在同一个包中
*
* 解决方案: 显式声明public修饰的构造函数
*/
public InnerClass() {
}
}
}
// 在外包调用
new OuterClass().new InnerClass(); // ... has protected access in ...
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员),因为内部类持有外部类的引用 OuterClass.this
如果属性名相同可以用OuterClass.this.来区分
外部类想要访问内部类只能通过创建内部类对象
new OuterClass().new Inner();
非静态内部类不能定义静态成员
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内
局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
局部内部类可以访问方法的局部变量,但是必须是final的,因为method在调用结束后就弹出栈了,而内部类还存在持有变量的引用,所以需要定义为常量
无法在外部去创建局部内部类,因为局部内部类是定义在方法中的,而方法是需要所在类的对象去调用的
public class OuterClass {
public void getNum(final String name){
class LocalInnerClass{
public void test(){
System.out.println(name);
}
}
new LocalInnerClass().test();
}
}
静态内部类
非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外部类,但是静态内部类却没有,这意味着:
- 它的创建是不需要依赖外部类的创建。
- 它不能使用任何外部类的非static成员变量和方法。
匿名内部类
没有访问修饰符
匿名内部类是唯一一种没有构造器的类,大部分匿名内部类用于接口回调,一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写
setComparable(new Comparable() {
@Override
public int compareTo(Object o) {
return 0;
}
});