我不能打电话给serve()下面的方法.
public class GenericService {
public static class Service<T> {
public void serve(T t) {
System.out.println(t.toString());
}
}
public static Service<?> service = new Service<String>();
public static void main(String[] args) {
service.serve("Hello World!"); // 'serve(capture<?>)' cannot be applied to '(java.lang.String)'
}
}
Run Code Online (Sandbox Code Playgroud)
如何强行调用此方法?
为什么Java不喜欢这样的调用?
UPDATE
问题不像ClassCastException提出的那样,因为在那种情况下我可以写
try {
service.serve("Hello World!"); // 'serve(capture<?>)' cannot be applied to '(java.lang.String)'
}
catch (ClassCastException e) {
System.err.println("You see!? This is why I was disliking your code!");
}
Run Code Online (Sandbox Code Playgroud)
但我不能.
为什么?
更新2
现在,每个人都说出来的新版本:
public static Service<? extends String> service = new Service<String>();
public static void main(String[] args) {
service.serve("Hello World!"); // 'serve(capture<?>)' cannot be applied to '(java.lang.String)'
((Service<String>)service).serve("Hello World!"); // Unchecked cast: 'GenericService.Service<capture<? extends String>>' to 'GenericService.Service<String>'
}
Run Code Online (Sandbox Code Playgroud)
什么问题是在这里(不认为这String是final)?
你误解了通配符的含义(这实际上是对Java中泛型通配符的常见误解).
Service<?>它不是意味着:一Service,可以接受任何类型.
它确实意味着:一个Service特定的,但未知类型.
你不能调用serve,传递它String,因为?代表的类型是未知的 - 编译器无法检查,只是通过查看变量的类型service,它所引用的实际服务是a Service<String>,a Service<Integer>还是a Service<Whatever>,所以它不知道是否应该允许传递String给serve方法.
为了保证类型安全,编译器除了不允许您调用该方法之外别无选择.
如何强行调用此方法?
您可以通过强制转换强制它:
((Service<String>) service).serve("Hello World!");
Run Code Online (Sandbox Code Playgroud)
(但请记住,铸造意味着你放弃了类型安全,一般来说你应该尽量避免铸造).
| 归档时间: |
|
| 查看次数: |
638 次 |
| 最近记录: |