可以使匿名类在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);
}
}
但是在此示例中无法访问它们,因为o
的类型为Object
:
$ 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
请注意,o
实际上不是Object
,而是扩展Object
的其他类的实例。此类有一个公共字段x
。这个班有名字吗?如何使o
成为正确的类型,以便我可以访问o.x
? (请注意it's possible to do this with reflection,但我想静态地执行此操作。)
答案 0 :(得分:3)
这个类有一个名字。它是A$1
。但是,您无法在编译时访问它(编译器会为您创建A$1
)。因此,您无法在没有反射的情况下访问该字段。
如果您在Eclipse中,可以使用来源菜单( Alt Shift S )→< strong>将匿名类转换为嵌套以自动将其转换为“真实”类。
或者,您可以:
class A {
public static void main(String[] args) {
I o = new I() {
public int x = 0;
{
System.out.println("x: " + x++);
System.out.println("x: " + x++);
}
public int getX() { return x; }
};
System.out.println(o.getX());
}
interface I {
public int getX();
}
}
编辑:这是一个非常邪恶的方式来实现这个不应该做:
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++);
}
public Object clone() {
// BAD BAD BAD
return x;
}
};
try {
System.out.println(o.clone());
} catch (CloneNotSupportedException cnse) {
assert false;
}
}
}
答案 1 :(得分:3)
您可以直接在匿名类创建表达式上访问它:
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);
}
}
但是,你不能再使用创建的对象了,所以它有点无用。
答案 2 :(得分:1)
Java不是C#,如果我没有弄错,那么允许这样的语法糖。你可以看一下sun.reflect.MagicAccessorImpl。但这门课程并不常见。仅用于自动生成的代码。如果扩展MagicAccessorImpl,JVM将不会执行字段访问级别检查。所以你可以这样做:
// ----- A.java -----
class A {
private int privateField = 5;
}
// ----- B.java -----
class B extends sun.reflect.MagicAccessorBridge {
public static void main(String[] args) {
A a = new A();
a.privateField = 10;
System.out.println(a.privateField);
}
}
// ----- MagicAccessorBridge.java -----
package sun.reflect;
public class MagicAccessorBridge extends MagicAccessorImpl {
// Since MagicAccessorImpl is package-private, we'll make a public bridge
}
答案 3 :(得分:0)
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(((A$1)o).x);
}
}
编译一次
$ java A.java
取消注释打印行
重新编译&amp;运行
$ java A.java && java A
x: 0
x: 1
2