views:

117

answers:

3

Imagine I have the following situation:

Test1.java

import java.lang.ref.WeakReference;
public class Test1
{
    public WeakReference fieldName;

    public init()
    {
        fieldName = new WeakReference(this);
        Test2.setWeakRef(fieldName);
    }
}

Test2.java

import java.lang.ref.WeakReference;
public class Test2
{    
    public static setWeakRef(WeakReference weakRef)
    {
        //at this point I got weakRef in an other class.. now, how do I get the field name this reference was created with? So that it returns exactly "fieldName", because that's the name I gave it in Test1.java?
    }
}

At the location of the comment I received the weak reference created in an other class. How would I retreive the field name that this weak reference was created with, in this case "fieldName"?

Thanks in advance.

+3  A: 

You can't.

What you're looking for ("fieldName") is the name of a field holding a reference to a WeakReference object. But the fact is, it doesn't matter that the class in question is WeakReference -- although that does confuse the discussion terribly. If you replaced "WeakReference" in all cases by "MyClass", we might be in better shape, and the answer would still hold.

The fact is, your weakRef variable contains a new reference to the same WeakReference object that fieldName points to; there's no way, just on that basis, to find out the name of the old reference.

Etaoin
I'm confused. Why would weakRef contain a new reference? I thought methods pass references rather than creating new ones?
Tom
What I mean is that `fieldName` is a variable containing a reference to an object and `weakRef` is an unrelated variable containing a reference to the same object.
Etaoin
I'm still confused about the references. I thought the reference would remain the same. Anyway, accepted your answer. Thanks.
Tom
+2  A: 

The only way would be using reflection. This is true for fields of any type, not only for weak references.

Field[] fields = Test1.getDeclaredFields();

for (Field field : fields) {
  if (field.getType().equals(WeakReference.class) {
    System.out.println(field.getName());
  }
}

Of course this example works only if you have a single WeakReference field in Test1.

Update: In case you have multiple reference fields, you need access to the object itself, in order to get and compare the actual value of a specific field with the value received. Like in this modified code example:

public class Test2 {    
  public static setWeakRef(Test1 instance, WeakReference weakRef) {
    Field[] fields = Test1.getDeclaredFields();

    for (Field field : fields) {
      if (field.getType().equals(WeakReference.class) {
        WeakReference value = (WeakReference) field.get(instance);
        if (value == weakRef) {
          System.out.println(field.getName());
        }
      }
    }
  }
}

Note that exception handling is left out for the sake of simplicity.

Péter Török
"Of course this example works only if you have a single WeakReference field in Test1" That's the problem. Can't I test if the reference of the field equals the weak reference, or something?
Tom
@Tom, see my update.
Péter Török
Thanks a whole lot!
Tom
A: 

The question is meaningless. There could be more than one such field, or zero.

EJP