不寻常的通用语法:数组.<String> asList(...)

卢声远*_* Lu 22 java generics

我找到了一个'不寻常'的通用语法,例如:

Arrays.<String>asList(...);
Collections.<String>emptyList();
Run Code Online (Sandbox Code Playgroud)

显然,这些方法的结果是通用的.这种语法是否用于类型检查?一个Object阵列不能为一个参数Arrays.<String>asList(...).

Ber*_*t F 23

<typearg>methodname 是显式指定泛型方法的类型参数的语法

使用泛型类时,通常必须指定类型参数(例如String):

ArrayList<String> list =  new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

使用泛型方法,通常不会传递类型参数:

public static <T> void foo(T param) {   }
...
String s = ...;
MyClass.foo(s);
Run Code Online (Sandbox Code Playgroud)

您将注意到我们没有在哪里明确指定代码我们想要的String版本foo,即没有<String>像我们在使用泛型类(List<String>)时看到的那样指定显式类型参数.

编译器正在做一些编译器魔术来根据上下文推断泛型类型参数.这是一件很棒的事情而且非常强大.

但是,有时编译器无法自动推断类型参数:

public static <T> void bar() { T myLocalVar = ...; ...  }
MyClass.bar();
Run Code Online (Sandbox Code Playgroud)

bar我们试图调用哪个具体版本,即这个调用的类型参数是什么?不知道?好吧,编译器也没有.我们必须显式声明类型参数,就像我们在使用泛型类时通常所做的那样:

MyClass.<String>bar();
Run Code Online (Sandbox Code Playgroud)

另见:


旁白:值得一提的是Java 7将添加所谓的菱形运算符,以允许我们让编译器在使用泛型类时推断类型参数:

ArrayList<String> list =  new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

ArrayList<String> list =  new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

Java 7中的钻石运算符有什么意义?


Mic*_*rdt 8

这是您为泛型方法显式指定类型参数的方法.在大多数情况下,编译器可以推断它,但有时需要明确说明.