[英]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.