我们不能在匿名类中声明构造函数。但是如果我需要使用局部变量的值来初始化匿名类的对象的状态,我该怎么做?
答案 0 :(得分:5)
您可以执行以下操作:
final int localVar = 5;
new Runnable() {
int innerVar = localVar; // <--- initialized here
public void run() {
System.out.println(innerVar);
}
}.run();
如果localVar
发生变异(非最终),您可以使用
...
final int tmp = localVar;
new Runnable() {
int innerVar = tmp;
...
...
另请注意,如果需要调用方法或进行其他初始化,您可以使用实例初始值设定项,而这通常是在构造函数中执行的操作:
final int localVar = 5;
new Runnable() {
int innerVar;
// Initialization block executed upon construction of this class
{
System.out.println("Initializing an anonymous Runnable");
innerVar = localVar;
}
public void run() {
System.out.println(innerVar);
}
}.run();
答案 1 :(得分:3)
您不能使用构造函数创建匿名类的假设并不完全正确。仅当从接口(不能具有构造函数)创建匿名类时才会出现这种情况。请参阅下面的示例:
public class Main {
public static class Razzy {
private final String name;
public Razzy(final String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static void main(final String[] args) {
final Razzy anonymous = new Razzy("Award") {
@Override
public String getName() {
return "Anonymous " + super.getName();
}
};
System.out.println(anonymous.getName());
}
}
这里的Razzy类有一个带String的构造函数。在main方法中,使用这个单个参数构造函数创建了Razzy的匿名子类。
输出结果为:
匿名奖
通过这种方式,您可以将局部变量传递给匿名类的构造函数。
请注意,匿名类也可以访问其封闭类的字段:
public class Main {
private static String input = "Award";
public interface Razzy {
public String getName();
}
public static void main(final String[] args) {
final Razzy anonymous = new Razzy() {
@Override
public String getName() {
return "Anonymous " + input ;
}
};
System.out.println(anonymous.getName());
}
}
具有相同的输出。
答案 2 :(得分:0)
问题是,您实际上并不需要定义构造函数。匿名类隐式访问封闭方法范围内的任何变量。它们只需要被声明为final(在Java 8中,不需要final关键字,但您仍然无法为它们重新赋值)。
public void enclosingMethod() {
final int localVariable = 42; // final is necessary
Runnable r = new Runnable() {
public void run() {
// look ma, no constructors!
System.out.println(localVariable);
}
};
r.run(); // prints 42
}