【问题标题】:Determining an object's variable name dynamically?动态确定对象的变量名?
【发布时间】:2010-05-09 23:36:53
【问题描述】:

假设我有一些对象:

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

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

谢谢!

【问题讨论】:

  • 对象在 Java 中没有名称。

标签: java reflection


【解决方案1】:

编译器不会保留您在代码中定义的变量名称,因此在运行时这是不可能的。

【讨论】:

  • +1 A、B、C 和 D 是对一个对象的引用,可以对一个对象有多个引用,这些对象不会跟踪谁引用了它们。所以比尔是对的,你需要在你的程序中跟踪它。您总是可以在列表中的项目和各个参考文献之间使用 ==。
【解决方案2】:

我不明白您为什么坚持与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);
 }
}

【讨论】:

    【解决方案3】:

    您可以在 SomeObject 中创建一个名为 name 的字符串字段并将名称存储在那里。

    尽管我讨厌这个答案:

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

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

    它不漂亮而且维护起来很烦人,但它可以工作

    【讨论】:

      猜你喜欢
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 2011-05-03
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多