我见过如下所示的方法:
protected <T extends ABC> T save( T Acd, boolean en) {
Run Code Online (Sandbox Code Playgroud)
它有什么作用?在Java中调用的这些类型的方法声明是什么?
我的问题很理论......这是Class.asSubclass(Javadoc)的签名:
public <U> Class<? extends U> asSubclass(Class<U> clazz)
Run Code Online (Sandbox Code Playgroud)
为什么返回类型中使用了通配符泛型?根据我对泛型的理解,更好的签名可能是:
public <U> Class<U> asSubclass(Class<U> clazz)
Run Code Online (Sandbox Code Playgroud)
因为你可以肯定演员
Class<? extends U>
Run Code Online (Sandbox Code Playgroud)
更简单
Class<U>
Run Code Online (Sandbox Code Playgroud)
Bloch在他的书"Effective Java"中建议(第137页,第28项):
不要将通配符类型用作返回类型.它不会为您的用户提供额外的灵活性,而是迫使他们在客户端代码中使用通配符类型.
这个选择背后的原因是什么?我错过了什么?非常感谢你提前.
编辑: 正如@egelev建议的那样,我确实可以用另一种方式表达我的问题......事实上,"按原样"返回输入参数将毫无意义.所以真正的问题是:与普通的强制转换相比,Class.asSubclass方法的真正用处是什么?如果出现强制转换问题,两者都会抛出ClassCastException.
可能已添加它以避免在特定情况下未经检查的转换:当您将asSubclass方法的结果直接传递给另一个请求约束类型参数的方法时,如此处(取自Effective Java,第146页):
AnnotatedElement element;
...
element.getAnnotation(annotationType.asSubclass(Annotation.class));
Run Code Online (Sandbox Code Playgroud)
上述方法的签名是:
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
Run Code Online (Sandbox Code Playgroud)
在我看来,asSubclass方法只是一种方法来做一个(事实上!)未经检查的强制转换没有正确的编译器警告...
这最终重新提出我以前的问题:签名
public <U> Class<U> asSubclass(Class<U> clazz)
Run Code Online (Sandbox Code Playgroud)
同样有效(即使很奇怪,我也承认)!它将与getAnnotation示例完全兼容,并且不会限制客户端代码强制它使用无意义的通配符泛型.
编辑2: 我认为我的一般问题已经解决了; 非常感谢你.如果有人有关于asSubclass签名正确性的其他好例子,请将它们添加到讨论中,我希望看到一个完整的例子,使用asSubclass和我的签名,显然不起作用.
我是Java中的Generics的新手.我对使用泛型的好处几乎没有怀疑.请参考以下代码 -
<T extends Bounceable> void goGreen(T ob);
void goGreen(Bounceable ob);
Run Code Online (Sandbox Code Playgroud)
这里Bounceable是一个界面.
有人可以解释一下上面定义的区别.它们都限制调用者将对象传递给它,而不是Bounceable类型.如果可以在界面风格中实现相同的代码,那么使用Generics有什么好处?提前致谢.