定义在一个类中或者方法中的类称为内部类.
内部类可以分为:
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类
内部类的共性
- 内部类仍然是一个独立的类,内部类会被编译成独立的.class 文件,但是在名字前面会加上外部类的类名和$符号
- 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
- 内部类声明成静态的,就不能随便的访问内部类的成员变量了, 此时就只能访问外部类的静态成员变量。
成员内部类
成员内部类是最普通的内部类,定义在一个类的内部中,如同一个成员变量一样,形式如下:
public class OutClass2 {
private int i = 1;
public static String str = "outclass";
class InnerClass { // 成员内部类
private int i = 2;
public void innerMethod() {
int i = 3;
System.out.println("i=" + i);
System.out.println("i=" + this.i);
System.out.println("i=" + OutClass2.this.i);
System.out.println("str=" + str);
}
}
}
public class TestClass {
public static void main(String[] args) {
//先创建外部类对象
OutClass2 outClass = new OutClass2();
//创建内部类对象
OutClass2.InnerClass in = outClass.new InnerClass();
//内部类对象调用自己的方法
in.innerMethod();
}
}
静态内部类
使用 static 关键字修饰的内部类就是静态类,静态内部类和外部类没有任何关系,可以看做是和外部类评级的类。
public class Outclass3 {
private String name;
private int age;
public static class InnerStaticClass {
private String name;
public String getName() {
return name;
}
public int getAge() {
return new Outclass3().age;
}
}
}
静态内部类很干净,没有持有外部类的引用,我们要访问外部类的成员只能 new 一个外部类的对象。
否则只能访问外部类的静态属性和静态方法,同理外部类只能访问内部类的静态属性和静态方法。
局部内部类
局部内部类是指在代码块或者方法中创建的类。
它和成员内部类的区别就是:局部内部类的作用域只能在其所在的代码块或者方法内,在其它地方是无法创建该类的对象。
public class OutClass4 {
private String className = "OutClass";
{
class PartClassOne { // 局部内部类
private void method() {
System.out.println("PartClassOne " + className);
}
}
new PartClassOne().method();
}
public void testMethod() {
class PartClassTwo { // 局部类内部类
private void method() {
System.out.println("PartClassTwo " + className);
}
}
new PartClassTwo().method();
}
}
(1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
(2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。
因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。
匿名内部类
顾名思义,没有名字的内部类
Car jeep=new Car();
在Java中操纵的标识符实际是指向一个对象的引用,也就是说 jeep
是一个指向 Car
类对象的引用,而右面的 new Car()
才是真正创建对象的语句。
这可以将 jeep
抽象的理解为 Car
类对象的“名字”,而匿名内部类顾名思义可以抽象的理解为没有“名字”的内部类:
匿名内部类的特点:
1.一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的事先或是覆盖。
3.类名没有意义,也就是不需要使用到。
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});123456
上面代码是 Android 中最常见的设置 button 的点击事件,其中 new OnClickListener() {…}
就是一个匿名内部类,在这里没有创建类对象的引用,而是直接创建的类对象。大部分匿名类用于接口回调。