How to access fields declared inside anonymous object?

别说谁变了你拦得住时间么 提交于 2019-12-11 02:26:28

问题


Java lets you declare new fields inside anonymous classes, but I can't figure out how to access them from outside, even setting them to public doesn't let me.

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);
   }
}

I get this compiler error:

$ 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

Why?


回答1:


Why?

It's because Object is the static type of the variable o, and Object doesn't have the property x. The following fails to compile for the exact same reason:

public class X {
  public int x;

  public static void main(String[] args) {
    Object o = new X();
    o.x = 3;
  }
}

Hopefully, your Java intuition is right on this example and you expect this to fail. So just transplant that intuition to your example.

How to access fields declared inside anonymous object?

Same way as you'd access x in my example: reflection.

Object o = new X();
o.getClass().getField("x").setInt(o, 3);

Why does it let me make public fields if I can't use them?

If it didn't let you make public fields, even reflection wouldn't work for you, at least not as simply as above.




回答2:


You could only do that by reflection. The class has no name, so you had to declare the variable o as an Object, and Object does not have that member. In other words, don't do this.




回答3:


You could acces the field by reflection:

    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 would be to name the class and use it as variable type, if you want to access field:

    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);



回答4:


You could access it directly on the anonymous class creation expression:

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);
   }
}

But then, you can't otherwise use the object created anymore, so it's kinda useless.




回答5:


Define an internal class that extends Object (in your specific case you should not write extends Object as it is done anyway. In your class, define your fields and than access them by reference of your type.

Example:

void func() {
     class MyInt extends Integer {
         boolean isSane = true;
     }
     MyInt intInstance = new MyInt();
     if (intInstance .isSane) {
         System.out.println("sane integer");
     }
}


来源:https://stackoverflow.com/questions/16489964/how-to-access-fields-declared-inside-anonymous-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!