2013-06-20 51 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特定於每個預期超類的評估站點。