奇怪的Java通用

时间:2010-01-12 15:50:54

标签: java generics

这是什么意思?

HashBiMap<Character, Integer> charOcc = HashBiMap.<Character, Integer> create();

6 个答案:

答案 0 :(得分:8)

它使用create()Character作为类型参数调用通用静态方法(Integer)。例如,如果您正在查看Google Java Collections,则声明具有以下签名:

public static <K,V> HashBiMap<K,V> create()

<K,V>部分自己指定那些是方法的类型参数。

C#中的等效调用将是以下之一:

HashBiMap.Create<Character, Integer>();
HashBiMap<Character, Integer>.Create();

取决于您是希望它是非泛型类型中的泛型方法,还是泛型类型中的非泛型方法。

Java中类型参数和类型参数的定位是不直观的IMO。

答案 1 :(得分:8)

create()是一种通用方法。由于它是静态的并且没有参数(因此没有类型推断),因此通过这种看起来很奇怪的.<Character, Integer>语法可以告诉它通用参数是什么的唯一方法。

编辑:在这种特定情况下,这实际上不是必需的;编译器可以从左侧推断泛型类型。但有时在其他情况下有必要,例如这个问题:Generic method in Java without generic argument

答案 2 :(得分:4)

这意味着static create()方法具有类型参数,例如:

public static <Character, Integer> HashBiMap<Character, Integer> create() {..}

答案 3 :(得分:3)

据推测,你认为它是右手边(RHS)很奇怪

HashBiMap.<Character, Integer> create();

通常,在调用泛型静态方法时,只需要在LHS上使用类型参数。但有时静态方法并不像您预期​​的那样推断出类型参数。在这些情况下,您还可以使用RHS上的类型参数,以便将类型参数强制转换为您想要的任何内容。这称为显式类型参数

以下是未正确推断类型参数的示例(改编自优秀的“Effective Java”一书):

实施例

给出静态方法

public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)
你可能认为你可以这样做:

Set<Integer> integers = ... ;
Set<Double> doubles = ... ;
Set<Number> numbers = union(integers, doubles);

如果您尝试它,您将收到以下错误消息:

Union.java:14: incompatible types
found : Set<Number & Comparable<? extends Number & Comparable<?>>>
required: Set<Number>
    Set<Number> numbers = union(integers, doubles);

如果编译器没有推断出你希望它具有的类型,你可以告诉它使用显式类型参数的类型。随着这个的增加 显式类型参数,程序干净地编译:

Set<Number> numbers = Union.<Number>union(integers, doubles);

答案 4 :(得分:1)

HashBiMap可能有一个方法

public static <K,V> HashBiMap<K,V> create(){...}

使用语法

HashBiMap<Character, Integer> charOcc = HashBiMap.<Character, Integer> create();

你传递的是K的字符和V的整数。

答案 5 :(得分:0)

如果您希望避免使用提供形式参数的繁琐语法,可以使用强制转换来键入提示。

使用您的示例,

Set<Integer> integers = ... ;
Set<Double> doubles = ... ;
Set<Number> numbers = union((Set<Number>)integers, doubles);

这将被编译器接受并避免必须使用

Set<Number> numbers = Union.<Number>union(integers, doubles);