匿名内部类 介绍
定义
匿名内部类:顾名思义,它是一个内部类,并且是没有名字的类,也简称为匿名类。
示例
//: innerclasses/Contents.java
package innerclasses; /* Added by Eclipse.py */
public interface Contents {
int value();
} ///:~
//: innerclasses/Parcel7.java
package innerclasses; /* Added by Eclipse.py */
// Returning an instance of an anonymous inner class.
public class Parcel7 {
public Contents contents() {
return new Contents() { // Insert a class definition
private int i = 11;
public int value() { return i; }
}; // Semicolon required in this case
}
public static void main(String[] args) {
Parcel7 p = new Parcel7();
Contents c = p.contents();
}
} ///:~
说明:
1. 上面代码中的
new Contents() {
// ...
// ...
};
并不是创建接口Contents的对象,(本身接口也是不能实例化的!)。
这种奇怪的语法指的是:创建一个继承自Contents的匿名类的对象。
通过new表达式返回的引用被自动向上转型为对Contents的引用。
2. 这里的Contents是个接口,除了可以是接口以外,还可以是普通类或者抽象类!
其他
- 如果基类的构造器需要参数,那也不影响,直接使用有参构造器即可!
//: innerclasses/Parcel8.java
package innerclasses; /* Added by Eclipse.py */
// Calling the base-class constructor.
public class Parcel8 {
public Wrapping wrapping(int x) {
// Base constructor call:
return new Wrapping(x) { // Pass constructor argument.
public int value() {
return super.value() * 47;
}
}; // Semicolon required
}
public static void main(String[] args) {
Parcel8 p = new Parcel8();
Wrapping w = p.wrapping(10);
}
} ///:~
//: innerclasses/Wrapping.java
package innerclasses; /* Added by Eclipse.py */
public class Wrapping {
private int i;
public Wrapping(int x) { i = x; }
public int value() { return i; }
} ///:~
- 匿名类中定义字段时,同样可以对其执行初始化操作,但是:
如果要使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的,就像下面在destination()的参数中看到的那样,如果没有加上final,那么在编译时将会报错!
//: innerclasses/Parcel9.java
package innerclasses; /* Added by Eclipse.py */
// An anonymous inner class that performs
// initialization. A briefer version of Parcel5.java.
public class Parcel9 {
// Argument must be final to use inside
// anonymous inner class:
public Destination destination(final String dest) {
return new Destination() {
private String label = dest;
public String readLabel() { return label; }
};
}
public static void main(String[] args) {
Parcel9 p = new Parcel9();
Destination d = p.destination("Tasmania");
}
} ///:~
//: innerclasses/Destination.java
package innerclasses; /* Added by Eclipse.py */
public interface Destination {
String readLabel();
} ///:~
- 除了初始化字段,能不能在匿名类中做一些类似于构造器的行为呢?
可以的!但是,有个问题:在匿名类中根本就没有命名的构造器(因为它根本没名字!),但通过实例初始化,就能够大大为匿名内部类创建一个构造器的效果,如下:
//: innerclasses/AnonymousConstructor.java
package innerclasses; /* Added by Eclipse.py */
// Creating a constructor for an anonymous inner class.
import static net.mindview.util.Print.*;
abstract class Base {
public Base(int i) {
print("Base constructor, i = " + i);
}
public abstract void f();
}
public class AnonymousConstructor {
public static Base getBase(int i) {
return new Base(i) {
{ print("Inside instance initializer"); }
public void f() {
print("In anonymous f()");
}
};
}
public static void main(String[] args) {
Base base = getBase(47);
base.f();
}
} /* Output:
Base constructor, i = 47
Inside instance initializer
In anonymous f()
*///:~
另外,一个例子:
//: innerclasses/Parcel10.java
package innerclasses; /* Added by Eclipse.py */
// Using "instance initialization" to perform
// construction on an anonymous inner class.
public class Parcel10 {
public Destination
destination(final String dest, final float price) {
return new Destination() {
private int cost;
// Instance initialization for each object:
{
cost = Math.round(price);
if(cost > 100)
System.out.println("Over budget!");
}
private String label = dest;
public String readLabel() { return label; }
};
}
public static void main(String[] args) {
Parcel10 p = new Parcel10();
Destination d = p.destination("Tasmania", 101.395F);
}
} /* Output:
Over budget!
*///:~
//: innerclasses/Destination.java
package innerclasses; /* Added by Eclipse.py */
public interface Destination {
String readLabel();
} ///:~
参考《Java编程思想 第4版》
第10章(内部类)-->10.6(匿名内部类)