2013-11-27 80 views
2

我有一個名爲A的Java基類和一個派生類名B. 我想從A(基類)訪問B的私有或公共變量的值。
我可以用這個代碼讀取變量名稱,但不是變量值:無法從基類訪問字段值

protected void loadValues() 
    { 
     Field[] fields = this.getClass().getDeclaredFields(); 
     for(Field field:fields){ 
      try { 
       xLog.info(field.getName()+"-"+field.get(this).toString()); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } 
     } 

的錯誤是: 進入現場不允許的。

我可以在C#中輕鬆完成。我怎麼能在java中做到這一點? 這是我做的在C#中的方法:你在訪問前場使用field.setAccessible(true);

private void loadValues() 
    { 
     foreach (var item in GetType().GetFields()) 
     { 
      Type type = item.FieldType; 
      object value = item.GetValue(this); 
      fields.Add(new Tuple<string, Type, object>(item.Name, type, value)); 
     } 
    } 

回答

3

例子:

public static class A { 
    public void test() throws Exception { 
     Field[] fields = this.getClass().getDeclaredFields(); 
     for (Field field : fields) { 
      field.setAccessible(true); 
      System.out.println(field.getName() + "-" + field.get(this).toString()); 
     } 
    } 
} 

public static class B extends A { 
    private String foo = "bar"; 
    public B() throws Exception { 
     super(); 
     test(); 
    } 
} 

public static void main(String[] args) throws Exception { 
    new B(); 
} 

打印:

foo-bar 
+0

還有一點小問題,如果foo沒有變量,會拋出一個execption。如何處理這個? –

+0

@ehsanshirzadi你是什麼意思*無變量*?你的意思是沒有設定值嗎?在這種情況下,你必須檢查'field.get(this)'不返回'null'。 – sp00m

+0

這是我的錯,我的意思是沒有價值。如果您在FOO中沒有值,則會拋出異常。 –

5

從外地讀書之前執行field.setAccessible(true);

真的真的再想一想之前在Java中實現這樣的循環依賴。是否真的是你的問題最好的解決方案來顛倒這樣的繼承?

反射是一個強大的工具,但通常有一個相當不潔的解決方案的氣味。

+0

您能否爲我的目的給我一個解決方案?我想爲我的實體擁有隻包含字段而不包含INSER,UPDATE方法的類。我想使用派生類的字段和值在基類中創建INSERT,UPDATE方法。你有任何解決方案或建議爲此目的? –

+1

用於此目的的組合物如何?實體不應該插入/更新自身。 Persister類可以爲每個實體(在那裏使用反射,或使用現有的持久框架,也許基於JPA的Hibernate)來實現。如果你需要的話,這會讓你的實體釋放真正的繼承關係。請記住,Java不支持從幾個基類中擴展。 – Matthias