[英]Accessing inner anonymous class members
除了使用反射来访问匿名内部类的成员之外,还有其他方法吗?
您可以使用本地类而不是匿名类。 看:
public class Test {
public static void main(String... args) {
class MyInner {
private int value = 10;
}
MyInner inner = new MyInner();
System.out.println(inner.value);
}
}
您可以仅在方法体中引用MyInner
类型。 因此,在方法之外,您将无法使用未在其超类(在本例中为java.lang.Object
)或接口中声明的字段/方法。
匿名内部类具有类型但没有名称。
您可以访问未由命名超类型定义的字段。 但是,一旦分配给命名类型变量,接口就会丢失。
显然,您可以从内部类本身访问字段。 添加代码的一种方法是通过实例初始化器:
final AtomicInteger y = new AtomicInteger();
new Runnable() {
int x;
{
x = 5;
doRun(this);
y.set(x);
}
public void run() {
... blah ...
}
};
匿名内部类表达式返回的值具有匿名类型,因此您有一次机会在类本身之外使用它:
final int y = new Runnable() {
int x;
{
x = 5;
doRun(this);
}
public void run() {
... blah ...
}
}.x;
您还可以通过类似于以下方式声明的方法传递它:
<T extends Runnable> T doRun(T runnable);
public class AccessAnonymous {
private Runnable runnable; // to have instance of the class
public static void main(String[] args) throws Exception {
AccessAnonymous a = new AccessAnonymous();
a.a(); // init field
Class clazz = a.runnable.getClass();
Field field = clazz.getDeclaredField("i");
field.setAccessible(true);
int int1 = field.getInt(a.runnable);
System.out.println("int1=" + int1);
}
public void a() {
runnable = new Runnable() {
private int i = 1;
public void run() {
i = 90;
}
};
runnable.run();// change value
}
}
在匿名类的情况下,在类引起的混乱和匿名的便利性之间也存在权衡。 复杂的类很少属于匿名,而是命名为私有内部。
在大多数匿名课程中,我们只需要“提供”知识,并且可以在构建时完成。 在一些匿名类(例如,返回值工具)中,我们也关心一个返回值。
我们知道,不应直接访问数据成员,而应使用getter setter。 如果您发现自己处于添加了大量getter和setter的情况,那么您可能无论如何都应该做错了,不应该使用匿名类。
如果它实现接口或扩展现有类,则可以访问接口或基类中定义的成员。
Fooz先生是对的,除了接口只能定义常数成员。 最好的方法是将getter / setter方法添加到您的界面,然后使用它们来获取您的价值。 但是对于每个匿名类,你必须定义那些方法(一种痛苦)。
如果您想要可读,可维护的代码,请不要使用匿名类。 如果您使用匿名类并希望可读,可维护的代码,则在需要访问该内部类中的元素时,请不要使用匿名类。 有办法这样做,但我恳求你不要使用任何这些黑客。 可读性胜过所有其他优点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.