Java允许你在匿名类中声明新字段,但我无法弄清楚如何从外部访问它们,即使将它们设置为公共也不会让我。
class A {
public static void main(String[] args) {
Object o = new Object() {
public int x = 0;
{
System.out.println("x: " + x++);
System.out.println("x: " + x++);
}
};
System.out.println(o.x);
}
}
我收到此编译器错误:
$ javac A.java && java A
A.java:10: cannot find symbol
symbol : variable x
location: class java.lang.Object
System.out.println(o.x);
^
1 error
为什么?
答案 0 :(得分:6)
为什么?
这是因为Object
是变量o
的静态类型,而Object
没有属性x
。以下原因完全无法编译:
public class X {
public int x;
public static void main(String[] args) {
Object o = new X();
o.x = 3;
}
}
希望您的Java直觉在这个示例中是正确的,并且期望这个失败。所以,只需将这种直觉移植到你的榜样中。
如何访问匿名对象内声明的字段?
与我在示例中访问x
的方式相同:反射。
Object o = new X();
o.getClass().getField("x").setInt(o, 3);
如果我不能使用公共字段,为什么它会让我公开?
如果它不允许你创建公共领域,即使反思也不适合你,至少不像上面那样简单。
答案 1 :(得分:3)
你只能通过反思来做到这一点。该类没有名称,因此您必须将变量o
声明为Object
,而Object
没有该成员。换句话说,不要这样做。
答案 2 :(得分:1)
您可以通过反射访问该字段:
Object o = new Object() {
public int x = 0;
{
System.out.println("x: " + x++);
System.out.println("x: " + x++);
}
};
System.out.println(o.getClass().getField("x").get(o));
如果要访问字段,Better Style将命名该类并将其用作变量类型:
class MyObject {
public int x = 0;
{
System.out.println("x: " + x++);
System.out.println("x: " + x++);
}
}
MyObject o = new MyObject();
System.out.println(o.x);
答案 3 :(得分:1)
您可以直接在匿名类创建表达式上访问它:
class A {
public static void main(String[] args) {
System.out.println(new Object() {
public int x = 0;
{
System.out.println("x: " + x++);
System.out.println("x: " + x++);
}
}.x);
}
}
但是,你不能再使用创建的对象了,所以它有点无用。
答案 4 :(得分:0)
定义一个扩展Object
的内部类(在您的特定情况下,您不应该写extends Object
,无论如何。在您的课程中,定义您的字段,然后通过引用您的类型来访问它们
示例:
void func() {
class MyInt extends Integer {
boolean isSane = true;
}
MyInt intInstance = new MyInt();
if (intInstance .isSane) {
System.out.println("sane integer");
}
}
答案 5 :(得分:0)
在Java 10之后,您也可以使用'var'魔术(局部变量类型推断)
class A {
public static void main(String[] args) {
// Object o = new Object() {
var o = new Object() {
public int x = 0;
{
System.out.println("x: " + x++);
System.out.println("x: " + x++);
}
};
System.out.println(o.x);
}
}