小编Cpt*_*asp的帖子

Class.asSubclass签名

我的问题很理论......这是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 effective-java

17
推荐指数
2
解决办法
1393
查看次数

有效的Java Item 9,CaseInsensitiveString示例是否正确?

我正在阅读本书的第二版,第36页.我不了解simmetry问题的解决方案:

@override public boolean equals(Object o) {
    return o instanceof CaseInsensitiveString &&
        ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
Run Code Online (Sandbox Code Playgroud)

如果我有,CaseInsensitiveString cis= new CaseInsensitiveString("hello")并且String s="hello"这种行为是非对称的,因为s.equals(cis) 是真的,但是cis.equals(s) 是假的......

我错过了什么?

java effective-java

4
推荐指数
1
解决办法
258
查看次数

标签 统计

effective-java ×2

java ×2

generics ×1