views:

65

answers:

3

Let's say I have some objects:

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

These constructors automatically add each object to the ArrayList so I can iterate over them but still maintain the variable names for direct access:

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

But then, let's say I want to output some debug info, and iterate through list and print out the NAME of each object? How can I do that? Essentially, when "SomeObject A = new SomeObject();" is executed, I want to use reflection (if possible) to determine that this variable's name is "A" (a String) and either store that in the object when the constructor executes, or determine it dynamically through reflection when referencing this object with the variable named "A". Does that make sense? How can I do this?

Thanks!

+3  A: 

The compiler doesn't keep the variable names you define in your code, so this isn't possible at run-time.

Bill the Lizard
+1 A,B,C and D are references to an object, It is possible to have multiple references to an object, The objects do not keep track of who refers to them. So Bill is right, you need to keep track of that in your program. You could always do an == between the items in your list and the individual references.
Romain Hippeau
+2  A: 

I don't see why you insist on working with List, as it seems that what you're looking for is a Map. An entry in a map is a named object, e.g. it has a key used to look up the entry in the map.

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

If your objects have names or need to know their names, then the object should have the name as a property. Using variable names or map keys for object identification is not good.

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

However, this is repetitive and you may want to refactor that into a more expressive design by introducing new classes:

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 may use a Map internally to manage the objects:

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

To iterate over either the object names or over the objects, the container can simply provide iterators for the keys of the map or the values of the map:

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

To use these iterators, you can do:

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
 }

}

If you directly use a Map, you can use the Map's Entry class, which is a key and value pair:

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);
 }
}
mhaller
A: 

you could just create a String field in SomeObject called name and store the name there.

OR

As much as I hate this answer:

Assuming you are creating the same objects every time, you could create a method which checks references, like so:

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

Its not pretty and it's annoying to maintain, but it works

CheesePls