簡體   English   中英

如何將類名作為 arguments 傳遞並在 GWT jsni 中調用常見的 static 方法?

[英]How to pass class-name as arguments and invoke common static methods in GWT jsni?

我有很多枚舉 class 並且都有一種通用方法。 我想調用該常用方法並使用 GWT jsni 方法動態返回。

假設我在不同的包中有以下枚舉類。

package A;

enum WidgetType{

   TEXT_BOX("A"),SVG("B");

   String type;

   WidgetType(String type){
      this.type = type;
   }

   public static WidgetType getDescriptiveValue( String type ){
        for(WidgetType widgetType : WidgetType.values()){
            if(widgetType.type.equalsIgnoreCase(type) ) return widgetType;
        }
        return null;
  }
}
package B;

enum MessageType{

   INFO("I"),WARN("W"),ERROR("E");

   String type;

   MessageType(String type){
      this.type = type;
   }

   public static MessageType getDescriptiveValue( String type ){
        for(MessageType messageType : MessageType.values()){
            if(messageType.type.equalsIgnoreCase(type) ) return messageType;
        }
        return null;
  }
}

在某種程度上,我會在 [A.WidgetType,B.MessageType] 之類的字符串中獲得枚舉完整限定名。

基於這個值,我想使用 JSNI 調用枚舉 class getDescriptiveValue 方法。

那么如何在 GWT jsni 中實現這一點。

當我嘗試將 class 名稱傳遞為 arguments 時,如下所示,我收到編譯時錯誤。

方法一:

native void enumValue(String enumClass,String value) /*-{
                console.log($entry(@enumClass::getDescriptiveValue(Ljava/lang/String;)(value)) );
            }-*/;

方法二:

native void enumValue(String enumClass,String value) /*-{
                console.log(@enumClass::getDescriptiveValue(Ljava/lang/String;)(value));
            }-*/;

我不知道有沒有辦法在 GWT 客戶端使用 Java 反射?

請建議我如何實現這一目標?

簡而言之,這不起作用 - java 類型/成員的 JSNI 語法只是一種編寫純代碼的方法,該代碼將在編譯時評估為您所描述的成員的 JS 等效項。 您不能簡單地將字符串轉換為 class 文字。

相反,根據您可能希望以這種方式支持的枚舉數量,考慮構建您正在尋找的枚舉類型和參數類型的Map<String, Map<String, Object>> 這將需要手動代碼來列出每個枚舉類型,或者需要代碼生成來為您執行此操作,並且具有不包括 JSNI 的額外優勢。

考慮一個像這樣的類型,它要求你給它的每個 Enum 實現一些 HasType 接口,這確保所有的都有一個 getType() 方法,所以它們可以以相同的方式反映。

public class EnumLookup {
  private final Map<String, Map<String, Object>> enumCache = new HashMap<>();

  /** Helper that you can call internally or externally to build up the cache */
  public <E extends HasType> void register(Class<E> type, E[] values) {
    Map<String, Object> values = enumCache.computeIfAbsent(type.toString(), classname -> new HashMap<>());
    for (E enumValue : values) {
      values.put(enumValue.getType().toLowerCase(), enumValue);
    }
  }
  /** And now the method you are trying to write */
  public <E extends HasType> void enumValue(String enumClass, String value) {
    // use of toLowerCase here and above ensures that type strings will match like
    // in your original java
    return (E) enumCache.get(enumClass).get(value.toLowerCase());
  }
}

然后在某處填充緩存

EnumCache cache = new EnumCache();

cache.register(WidgetType.class, WidgetType.values());
cache.register(MessageType.class, MessageType.values());
//...

另一種方法是讓 map 包含一個Function<String, Object> ,並使用它通過方法引用指向getDescriptiveValue 然后注冊將如下所示:

cache.register(WidgetType.class, WidgetType::getDescriptiveValue);
cache.register(MessageType.class, MessageType::getDescriptiveValue);

暫無
暫無

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

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