簡體   English   中英

Java反射設置屬性

[英]Java Reflection to set attributes

我有一個具有許多可設置/可獲取的屬性的類。 我想使用反射來設置這些屬性,但是關於實現我有兩個問題

這是我班上的一些簡化代碼

class Q {

  public String question_1;
  public String question_2;
  public String question_3;
  public String answer_1;
  public String answer_2;
  public String answer_3;
  //etc. etc.  Many String attributes

  // … constructor and other stuff are omitted

  // here is my method for "dynamically" setting each attribute
  public void set_attribute(String a_raw_string, String my_field) {
    try {
      Class cls = Class.forName("com.xyz.models.Q");
      Field fld = cls.getField(my_field);
      fld.set(this, a_raw_string);
  }
  catch (Throwable e) {
      System.err.println(e);
  }
}

然后,我像這樣設置各個字段:

Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.

這有效(即,當我調用set_attribute時設置實例變量。

但是,它們僅在實例變量被聲明為public時起作用。 當它們被聲明為私有時,我得到一個NoSuchFieldException

問題1:當字段為私有時,為什么會出現該錯誤? 我的天真的假設是,由於set_attribute函數是類的一部分,因此它應該可以不受限制地訪問實例變量。

問題2:我認為我可能對此問題思考過多(即,我不應該使用反射來設置變量)。 是否有更推薦的方法? 我之所以要使用反射,是因為要聲明大量的setter方法很麻煩……所以我想知道是否有人以更好的方式解決了這種煩惱。

謝謝!

我想我可能對此想法太想了(即,我不應該以這種方式使用反射來設置變量)

是的 反射是相當緩慢的,僅應作為最后的手段。 如果只是為了避免有太多冗余代碼,請考慮使用自動代碼生成。 對於純數據對象,我強烈建議使用協議緩沖區 它將生成getters / setters(您只需要聲明字段)。 另外,它還允許在C ++,Java和Python之間輕松進行數據通信。

如果您有一個具有很多字段但又不是純數據對象的類...那么

  1. 您應該考慮所有字段是否應該都是可變的。 (您真的需要二傳手嗎?)
  2. 字段是否應該可見。 (您是否需要任何訪問器?)

通常,將字段設置為“最終”,在構造函數中對其進行初始化,並且不提供任何訪問或通過已實現的接口提供有限的訪問,通常是一個好主意。

使用setter方法是為類成員變量設置值的公認方法,因此絕對不應該使用反射,因為代碼將更難以理解,運行起來也更加緩慢。

大多數IDE(例如Eclipse或NetBeans)都包含用於自動為類的字段創建getter和setter方法的工具。

  1. 當它們是私有的時,您需要調用fld.setAccessible(true);
  2. 是的,為什么不直接設置字段並避免反射呢? 您似乎並沒有動態地進行任何操作。 只是他們是私人的-為什么? 也許您的意思是公開獲取者/設置者並使字段私有? 如果是這樣,那么您應該只調用公共設置器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM