如何在Java中使用通配符调用类的方法?

Dim*_*ims -6 java generics

我不能打电话给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)

什么问题是在这里(不认为这Stringfinal)?

Jes*_*per 8

你误解了通配符的含义(这实际上是对Java中泛型通配符的常见误解).

Service<?>不是意味着:一Service,可以接受任何类型.

确实意味着:一个Service特定的,但未知类型.

你不能调用serve,传递它String,因为?代表的类型是未知的 - 编译器无法检查,只是通过查看变量的类型service,它所引用的实际服务是a Service<String>,a Service<Integer>还是a Service<Whatever>,所以它不知道是否应该允许传递Stringserve方法.

为了保证类型安全,编译器除了不允许您调用该方法之外别无选择.

如何强行调用此方法?

您可以通过强制转换强制它:

((Service<String>) service).serve("Hello World!");
Run Code Online (Sandbox Code Playgroud)

(但请记住,铸造意味着你放弃了类型安全,一般来说你应该尽量避免铸造).