簡體   English   中英

Java:使用反射注入字段的最快方法是什么?

[英]Java: What is the fastest way to inject fields using reflection?

假設,我有很多類,它們是使用Java反射構造的(出於某種原因)。 現在我需要將值后注入到字段中,這些字段使用@PostInject注釋。

public class SomeClass {
  @PostInject
  private final String someString = null;

  public void someMethod() {
    // here, someString has a value.
  }
}

我的問題是: 使用反射設置字段的快速方法什么?
請記住,我需要經常在很多課程上這樣做,這就是性能相關的原因。

這個偽代碼顯示了我通過直覺做的事情:

  • 得到班上的所有領域
    clazz.getFields();
  • check,用@PostInject注釋
    eachField.getAnnotation(PostInject.class);
  • 使這些字段可訪問
    eachAnnotatedField.setAccessible(true);
  • 將它們設置為某個值
    eachAnnotatedField.set(clazz, someValue);

我害怕獲得所有領域是最慢的事情。
當我從一開始就知道它時,我可以得到一個領域嗎?

注意:我不能讓類實現一些接口,這將允許使用方法設置字段。 我需要 POJO。

注2:為什么我要進行現場注入:從API用戶的角度來看,必須能夠使用最終字段。 此外,當API先驗地不知道字段的類型和數量時,不可能使用接口實現字段初始化。

注2b:從用戶的角度來看,最終合同沒有被打破。 它保持最終。 首先,字段初始化,然后無法更改。 順便說一句:有很多API使用這個概念,其中一個是JAXB(JDK的一部分)。

在構造對象並保存在對象本身中獲得的注釋字段集或者通過將類的單獨映射保留到注釋字段集之后,如何執行步驟1到3?

然后,當您需要更新對象中的注入字段時,從對象或單獨的映射中檢索集合並執行步驟4。

另一種選擇,正如你所說,你從一開始就知道幾個有關的領域,就是只詢問那些領域或方法。

示例:請參閱java / lang / Class.html中的 getDeclaredMethodgetDeclaredField

不知道它是否有用,但這個項目看起來會像你想要的那樣。 引用:

一組反射實用程序和雜項實用程序,與處理類及其字段相關,沒有依賴項,與java 1.5和泛型兼容。

實用程序緩存反射數據以進行高性能操作,但使用弱/軟緩存來避免保持打開的ClassLoaders並導致緩存永久存在於內存中。 支持使用您自己的覆蓋緩存機制的功能。

您可以利用允許在對象構造上注入依賴關系的現有框架。 例如, Spring允許使用aspectj編織來做到這一點 一般的想法是你在spring級別定義bean依賴項,只是標記目標類以建議它們的對象創建。 實際依賴性解析邏輯直接注入類字節代碼(可以使用編譯或加載時編織)。

使用反射執行任何操作的最快方法是盡可能緩存實際的Reflection API類。 例如,我最近制作了一個又一個動態的POJO操縱器,我認為這是每個人最終在某些方面做的事情之一,這使我能夠做到這一點:

Object o = ...
BeanPropertyController c = BeanPropertyController.of(o);

for (String propertyName : c.getPropertyNames()) {
        if (c.access(propertyName) == null && 
            c.typeOf(propertyName).equals(String.class)) {
                c.mutate(propertyName, "");
        }
}

它的工作方式是它基本上有一個控制器對象延遲加載bean的所有屬性( 注意:涉及一些魔法 ),然后只要實際控制器對象處於活動狀態就重用它們。 我只能說,通過保存Method對象本身,我設法將那個東西變成了一個該死的快事,我為此感到自豪,甚至考慮發布它,假設我可以設法解決版權等問題。

暫無
暫無

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

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