簡體   English   中英

動態創建字段和方法

[英]Create Fields and methods dynamically

我想為給定的類添加新的字段(變量)和封裝方法。 例如:班級名稱 Student 沒有任何字段,如下所示:

public class Student implements Serializable{

}

然后在我的應用程序中創建了一個實例;

Student s=new Student();

我想添加在運行時學生類不存在的新方法。例如:我想添加一個名為studentName的字段,以及getStudentName()setStudentName()方法。

那么在運行時學生對象會是這樣的;

public class Student implements Serializable{

    private String studentName;

    public void setStudentName(..){}
    public String getStudentName(){return ...;}
}

在我的應用程序中,對象被寫入一個文本文件,並且所有相同類型的對象都沒有所有變量。 因此,我只想添加必需的字段以節省內存。

有沒有辦法做到這一點? 任何示例代碼或鏈接?

編輯:否則我們可以創建一個類並創建不存在的實例嗎?

編輯 2:感謝你們所有人的回答並獲得了許多信息和想法。 並從你的建議中改變了一條更好的道路

為什么不創建一個值的HashMap呢? 效率更高,並具有您正在尋找的所有靈活性。

public class Student
{
      private HashMap<String, String> values;

      public Student()
      {
          this.values = new HashMap<String, String>();
      }

      public void addValue(String name, String value)
      {
          values.put(name, value);
      }

      public String getValue(String name)
      {
          return values.get(name);
      }
}

為什么是 HashMap?

您說過所有對象可能具有不同的值,您將通過String定義這些新方法和屬性。 嗯..這將實現該功能而無需任何可怕的字節碼操作。 例如:

String attrName = "name";
String attrValue = "jim";
Student stu = new Student();
stu.addValue(attrName, attrValue);

目前,您的HashMap只有一個值。 您唯一需要面對的是HashMap對象本身和兩個方法,坦率地說,這是一個更整潔的解決方案的公平權衡。

為此,您可以使用字節碼檢測庫,如JavassistASM 以下是使用 Javassist 添加字段或方法的示例

雖然字節碼操作是可能的,但這樣做並不明智,特別是如果您打算這樣做以“節省內存”。 您不太可能擁有如此多的數據以致於產生影響,如果您這樣做了,您無論如何都會將它們存儲在數據庫中。

您可以使用DynaBean 和 DynaClass,而不是編寫自己的基於HashMap的解決方案:不僅支持簡單的屬性,還支持索引(Array)和映射(Map)。
可以內省 DynaBean 以獲取屬性和值,因此您可以轉儲到文件但是使用此解決方案您只是“模擬”一個 bean,您的Student類並不真正包含字段和訪問器(您稱之為Student.getClass().getDeclaredField()你會得到一個空數組)。

如果您需要編寫一個“真正的”java java.lang.Class Javassist(我的首選,我曾經解決過與您的問題類似的解決方案)或 ASM(或 CGLIB)是最好的選擇。

實際上,不是在 Java 中。 在其他語言(如 Javascript)中,這是可能的。

我不相信這在 Java 中是否可行,但我確定它只會添加到內存中,因為如果您動態添加它們,則必須事先設置它們 + 動態添加它們的代碼。

Java 不是動態編程語言,因此即使某些高級方法可能允許您這樣做,我也不建議遵循該路線。

該場景的 Java 習慣用法是將字段值存儲在(哈希)映射中。 因此,您將有幾個通用訪問器來設置或獲取所有屬性值,並且您需要在訪問器中指明要更改的屬性的名稱。

然而,除非屬性的最大數量相當大並且大多數對象只有少量此類屬性的值,否則此解決方案不會節省內存。

   public class Entity {
   
      // 5 is an estimate for the number attrs.
      private Map<String,Object> attrs = new HashMap<>(5); 

      public Object getAttribute(String name) { return attrs.get(name); }

      public void setAttribute(String name, Object obj) { attrs.put(name,obj); } 

   }

如果您管理有關可能的屬性及其值類型的元數據,則可以實施一些運行時類型檢查。

暫無
暫無

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

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