动态确定对象的变量名称?

时间:2010-05-09 15:03:05

标签: java reflection

假设我有一些对象:

ArrayList<SomeObject> list = new ArrayList<SomeObject>();
SomeObject A = new SomeObject();
SomeObject B = new SomeObject();
SomeObject C = new SomeObject();
SomeObject D = new SomeObject();

这些构造函数会自动将每个对象添加到ArrayList中,因此我可以迭代它们,但仍然保留变量名称以便直接访问:

public SomeObject(){
   // init stuff here
   list.add(this);
}

但是,那么,假设我想输出一些调试信息,并遍历列表并打印出每个对象的NAME?我怎样才能做到这一点?基本上,当“SomeObject A = new SomeObject();”时执行时,我想使用反射(如果可能)来确定此变量的名称是“A”(一个字符串),并在构造函数执行时将其存储在对象中,或者在引用此对象时通过反射动态确定它变量名为“A”。那有意义吗?我怎么能这样做?

谢谢!

3 个答案:

答案 0 :(得分:3)

编译器不保留您在代码中定义的变量名称,因此在运行时无法实现。

答案 1 :(得分:3)

我不明白为什么你坚持使用List,因为看起来你正在寻找的是Map。地图中的条目是命名对象,例如它有一个用于在地图中查找条目的密钥。

Map<String,SomeObject> map = new HashMap<String,SomeObject>();
map.put("A",new SomeObject());
map.put("B",new SomeObject());

如果您的对象具有名称或需要知道其名称,则该对象应将该名称作为属性。使用变量名称或映射键进行对象识别并不好。

Map<String,SomeObject> map = new HashMap<String,SomeObject>();
map.put("A",new SomeObject("A"));
map.put("B",new SomeObject("B"));

然而,这是重复的,您可能希望通过引入新类将其重构为更具表现力的设计:

SomeObjects objects = new SomeObjects();
SomeObject objectA = objects.create("A");
SomeObject objectB = objects.create("B");
// The container can manage references if you like to
SomeObject objectA = objects.get("A");

SomeObjects可以在内部使用Map来管理对象:

class SomeObjects {
  Map<String,SomeObject> objects = ...;
  public SomeObject create(String name) {
   SomeObject newObject = new SomeObject(name);
   objects.put(name,newObject);
   return newObject;
  }
  public SomeObject get(String name) {
   return objects.get(name);
  }
}

要迭代对象名称或对象,容器可以简单地为地图的键或地图的值提供迭代器:

public class SomeObjects {
 Map<String,SomeObject> objects = ...;
 public Iterator<SomeObject> objects() {
   return objects.values().iterator();
 }
 public Iterator<String> names() {
   return objects.keySet().iterator();
 }
}

要使用这些迭代器,您可以执行以下操作:

public void test() {
 SomeObjects objects = ...;

 for(SomeObject obj : objects.objects()) {
   // Do something with the object
 }

 for(String objName : objects.names()) {
   // Do something with the object name
 }

}

如果你直接使用Map,你可以使用Map的Entry类,这是一个键和值对:

public void test() {
 Map<String,SomeObject> objects = new HashMap<String,SomeObject>();
 objects.put("A",new SomeObject());

 for(Entry entry : objects.entrySet()) {
  System.out.printlnt("Processing object with name: " + entry.getKey());
  SomeObject obj = entry.getValue();
  doSomethingWith(obj);
 }
}

答案 2 :(得分:0)

你可以在SomeObject中创建一个名为name的String字段,并在那里存储名称。

OR

尽管我讨厌这个答案:

假设您每次都创建相同的对象,您可以创建一个检查引用的方法,如下所示:

public void referenceChecker(SomeObject thing){
     if( A == thing) System.out.println("A");
     else if(B == thing) System.out.println("B");
     //etc etc
}

它不漂亮,维护很烦人,但它有效