2013-06-20 45 views
2

我参考对象A,这是抽象的。该对象也是在任何时间对象的实例B,CD获取抽象类中私有最终字段的引用

不管延伸类的,我需要内到一定类型的私人最终场的参考。

我不知道该字段的名称,只有它的类型,这是抽象类中所有其他字段所独有的。我无法更改四个列出的类中的任何一个的代码。使用getDeclaredFields()可以返回我当时拥有的任何扩展类中的字段。

我怎样才能得到这个领域的参考?

+1

听起来像你正在阅读谜语 –

+1

让我们看看一些代码示例。 –

+0

威姆霍尔,如果它隐藏得很好,它可能是故意的,对吧?你为什么需要访问它?没有其他方法吗? – fge

回答

2

如果你没有直接的上课它的自我,那么你可以做一些事情如下 -

Field[] fields = obj.getClass().getSuperclass().getDeclaredFields(); 
for(Field field : fields) { 
    if(field.getType() == String.class) { //assume the type is String 

    } 
} 

但是,如果你有机会到类,那么这将是

Field[] fields = B.class.getSuperclass().getDeclaredFields(); 

或者甚至

Field[] fields = A.class.getDeclaredFields(); 
+0

尝试了一切,但getSuperclass()。我现在明白了。谢谢! – WildBamaBoy

2
import java.lang.reflect.Field; 

abstract class A { 
    private final String secret = "got it"; 
} 

class B extends A { 
    private final String secret = "try again"; 
} 

public class Test { 

    public static void main(String[] args) throws IllegalAccessException { 
     Class neededType = String.class; 
     A a = new B(); 
     Class c = a.getClass(); 
     Class sc = c.getSuperclass(); 
     Field flds[] = sc.getDeclaredFields(); 
     for (Field f : flds) { 
      if (neededType.equals(f.getType())) { 
       f.setAccessible(true); 
       System.out.println(f.get(a)); 
      } 
     } 
    } 

} 
2

您需要CA LL getDeclaredFields()对A类本身,然后使用反射来设置访问的领域正是如此

import java.lang.reflect.Field; 
import java.lang.reflect.Modifier; 

public class Test{ 

    public static void main(String args[]){ 
    B someB = new B(); 
    B otherB = new B(); 

    Field uniqueField = null; 

    for(Field f : A.class.getDeclaredFields()){ 
     if(!Modifier.isFinal(f.getModifiers())) 
     continue; 
     if(!UNIQUE.class.isAssignableFrom(f.getType())) 
     continue; 

     uniqueField = f; 
     break; 
    } 
    if(null == uniqueField) 
     throw new NullPointerException(); 

    uniqueField.setAccessible(true); 

    try{ 
     System.out.println(uniqueField.get(someB) != uniqueField.get(otherB)); 
    }catch(IllegalArgumentException | IllegalAccessException e){ 
     throw new RuntimeException(e); 
    } 
    } 

} 

class UNIQUE{ 
} 

class A{ 
    private final UNIQUE u; 
    private final String someOtherMember = ""; 

    A(){ 
    u = new UNIQUE(); 
    } 

} 

class B extends A{ 

} 

如果你没有直接引用类或如果有一个以上的超具有此独特的领域,那么你可以遍历每一个(确保检查每个停止你没有爬上来的所有对象的方式)通过上述

Class<?> clazz = someB.getClass(); 
    classClimb: do{ 
    for(Field f : clazz.getDeclaredFields()){ 
     if(!Modifier.isFinal(f.getModifiers())) 
     continue; 
     if(!UNIQUE.class.isAssignableFrom(f.getType())) 
     continue; 

     uniqueField = f; 
     break classClimb; 
    } 
    }while(Object.class != (clazz = clazz.getSuperclass())); 
    if(null == uniqueField) 
    throw new NullPointerException(); 

    uniqueField.setAccessible(true); 

    try{ 
    System.out.println(uniqueField.get(someB) != uniqueField.get(otherB)); 
    }catch(IllegalArgumentException | IllegalAccessException e){ 
    throw new RuntimeException(e); 
    } 

更多类似这样的做的事情的例子请记住,在如果您需要对每个对象进行反射,请执行一些缓存操作,或者使用多个refl特定于每个预期超类的评估站点。