2013-10-13 91 views
1

說我有下面的類:是否有可能在Java中動態設置對象屬性(沒有反射)?

class Foo 
{ 
    public String bar; 
    public String baz; 
} 

而且我有下面的代碼,在另一個類:

Foo foo = new Foo(); 
String[] properties = {"bar", "baz"}; 
String[] values = {"barValue", "bazValue"}; 

是否可以遍歷properties陣列,並用它來設置的值Foo?例如:

for (int i = 0; i < properties.length; i++) 
{ 
    foo[ properties[i] ] = values[i]; 
} 

是類似上述可能嗎?

+1

但爲什麼沒有反射限制? – anubhava

+1

只是使用'HashMap'。 – roippi

+0

沒有反思,這是不可能的。 – UDPLover

回答

5

有點像上面的可能嗎?

隨着你定義它們的屬性,你唯一的選擇是:

  • 書寫或生成Java代碼(或字節碼)來指代領域的foo.barfoo.baz

  • 使用反射。

如果您需要動態屬性,請使用Map對象;例如一個HashMap<String, String>


關於你的說明性示例中,這不會/不能工作,因爲:

  • 定期對象字段不能被索引像陣列,並且
  • 不像C++,Python和其他語言,Java不支持任何核心語言結構(除了方法)的特定重載。

Java是不支持這種事情的動態語言。你需要學習如何生活,或者使用不同的語言。


您這樣說:

的反思應該是不好的性能。

嗯是的,但它是相對的。反射訪問或更新字段可能比使用普通Java代碼訪問/更新字段慢10到100倍。但是,如果您只是偶爾執行此操作,則性能開銷可能與此無關。如果它確實成爲一個問題,那麼你的選擇包括手寫或生成代碼。例如:

public class Foo 
{ 
    public String bar; 
    public String baz; 

    public void setNamedProperty(String name, String value) { 
     switch (name) { 
     case "bar": 
      bar = value; 
      break; 
     case "baz": 
      baz = value; 
      break; 
     default: 
      throw new IllegalArgumentException("Unknown property name"); 
     } 
    } 
} 

對於什麼是值得的,該代碼將是大約隨着時間的有效,因爲在支持動態特性的語言設置動態屬性。 (我懷疑這將是節省空間,因爲動態屬性是使用本地編碼哈希表通常實現的。)

+0

我沒有「寫或生成Java代碼(或字節碼)來引用字段foo.bar」???請您詳細說明...... –

+0

@KanagaveluSugumar - 例如,「編寫一個setter方法並調用它」。請注意,這些是動態屬性的替代*。 –

1

您可以使用Introspection,它是更好的,當你面對Java組件的方式。

缺點是:

  • 它將調用的getter/setter方法,如果它們存在,或將直接接入領域,如果沒有的getter/setter方法和字段都是公開的。
  • 您可以遍歷屬性,因爲它給了你一個PropertyDescriptor的數組。
  • 它支持BeanInfo類,
    • ,所以你可以配置你的bean屬性
    • 定義具有不同的命名約定訪問/存取器(不是getter或setter)
  • 您可以使用庫,例如​​Apache Commons BeanUtilsSpring BeanWrapper API

欲瞭解更多信息,請參閱java.beans.Introspector javadocs。

順便說一下,據我所知,Interospection建立在反射之上,所以它使用反射本身。

相關問題