Javagenerics:generics仅定义为返回types

我正在寻找GWT的一些GXT代码,我碰到了generics的这种用法,我无法在Java教程中find另一个例子。 如果你想查看所有的代码,类名是com.extjs.gxt.ui.client.data.BaseModelData 。 这里是重要的部分:

 private RpcMap map; public <X> X get(String property) { if (allowNestedValues && NestedModelUtil.isNestedProperty(property)) { return (X)NestedModelUtil.getNestedValue(this, property); } return map == null ? null : (X) map.get(property); } 

X在类中或层次结构中的任何地方都没有被定义,当我在eclipse中点击“去声明”时,它只是进入公共方法签名中的<X>

我试着用以下两个例子来调用这个方法来看看会发生什么:

 public Date getExpiredate() { return get("expiredate"); } public String getSubject() { return get("subject"); } 

他们编译并显示没有错误或警告。 我想至less我必须做一个演员才能使这个工作。

这是否意味着generics允许一个神奇的返回值,可以是任何东西,只会在运行时炸掉? 这与仿制药应该做什么似乎是相反的。 任何人都可以解释这个给我,也可能给我一个链接到一些文件,解释这个更好一点? 我已经阅读了Sun的23页关于generics的pdf,并且返回值的每个示例都是在类级别定义的,或者是在传入的参数之一中定义的。

该方法返回所期望的types( <X>在方法中定义,并且是绝对无限的)。

这是非常非常危险的,因为没有规定返回types实际上匹配返回的值。

这样做的唯一好处是,您不必强制返回任何types的通用查找方法的返回值。

我会说:小心使用这样的构造,因为你几乎失去了所有的types安全性,只有在每次调用get()时都不必写明确的types转换。

是的:这几乎是在运行时爆发的黑魔法,并打破了generics应该实现的整个想法。

types在方法中声明。 那就是“ <X> ”的意思。 该types的范围仅限于该方法,并且与特定的调用相关。 testing代码编译的原因是编译器试图确定types,只有在不能的时候才会报错。 有些情况下你必须明确。

例如, Collections.emptySet()的声明是

 public static final <T> Set<T> emptySet() 

在这种情况下,编译器可以猜测:

 Set<String> s = Collections.emptySet(); 

但如果不行,你必须input:

 Collections.<String>emptySet(); 

我只是想找出一个GXT类相同的东西。 具体来说,我试图调用一个方法的签名:

 class Model { public <X> X get(String property) { ... } } 

从你的代码调用上述方法,并把它转换为一个string我做到以下几点:

 public String myMethod(Data data) { Model model = new Model(data); return model.<String>get("status"); } 

上面的代码将调用get方法,并告诉它返回的types应该返回为String。

如果这个方法和你在同一个类中,我发现我必须用“this”来调用它。 例如:

 this.<String>get("status"); 

正如其他人所说,这是GXT团队相当sl and和危险。

BaseModelData在编译时引发未经检查的警告,因为它是不安全的。 像这样使用,你的代码将在运行时抛出一个ClassCastException,尽pipe它本身没有任何警告。

 public String getExpireDate() { return get("expiredate"); } 

有趣的是,从RpcMap(GXT API 1.2)

得到的标题:

 public java.lang.Object get(java.lang.Object key) 

在那里有一个通用的参数<X>没有实际的效果,除了你不需要在所有的地方说“对象”。 我同意另一张海报,这是马虎,有点危险。

是的,这是危险的。 通常情况下,你会保护这样的代码:

 <X> getProperty(String name, Class<X> clazz) { X foo = (X) whatever(name); assert clazz.isAssignableFrom(foo); return foo; } String getString(String name) { return getProperty(name, String.class); } int getInt(String name) { return getProperty(name, Integer.class); }