繁体   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