匿名内部类没有具体的类名也没有class关键字,因为匿名内部类是直接使用new来生成一个对象的引用。创建匿名内部类时会立即创建一个该类的实例,该类的定义会立即消失,就像一个表达式,对于只会使用一次的局部类的场景可以用匿名类来代替
一般匿名内部类创建模版
Outer outer = new Outer(args) {
//匿名内部类的类体部分
}
//e.g.
public class AnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
//局部类
class EnglishGreeting implements HelloWorld {
String name = "world";
public void greet() {
greetSomeone("world");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
HelloWorld englishGreeting = new EnglishGreeting();
//匿名类
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
}
}
在上述例子中,创建的类只需要一个实例frenchGreeting
和frenchGreeting
,由于每个类只需使用一次,如果都新建一个类会难以管理,因此可以使用匿名类。匿名类经常使用在多线程中,使用多线程时,一般先继承Thread类或者实现Runnable接口,然后再去调用它的方法,而每个任务一般都不一样,每次都新建一个类显然会很复杂。
注意:
- 匿名类必须是继承一个类或者实现一个接口,并且只能继承一个类或者实现一个。匿名类不能是抽象类,必须实现父类或者接口的所有抽象方法
- 匿名类可以访问外部其封闭类的成员,但无法访问那些不是final或者effectively final的局部变量
- 对于匿名类中的成员,匿名类具有跟局部类相同的限制
- 匿名类中的声明的类型变量,会覆盖掉外部区域中的同名的变量
- 不能在匿名类中声明静态代码块、静态成员(除非是常量)与静态方法
匿名内部类初始化法:
第一层花括号定义了一个继承于HashMap的匿名内部类
第二层花括号实际上是这个匿名内部类实例初始化块(或称为非静态初始化块)
通过new得到这个HashMap的子类的实例并向上转型为HashMap的引用,但功能上与HashMap没有任何区别
HashMap map = new HashMap(); //创建实例对象
HashMap map = new HashMap(){
{
put("A",1);
put("B",2);
}
};