What does this mean?
HashBiMap<Character, Integer> charOcc = HashBiMap.<Character, Integer> create();
What does this mean?
HashBiMap<Character, Integer> charOcc = HashBiMap.<Character, Integer> create();
It's calling a generic static method (create()
) using Character
and Integer
as the type arguments. For instance, if you're looking at the Google Java Collections, the declaration has this signature:
public static <K,V> HashBiMap<K,V> create()
The <K,V>
part on its own specifies that those are type parameters for the method.
The equivalent call in C# would be one of:
HashBiMap.Create<Character, Integer>();
HashBiMap<Character, Integer>.Create();
depending on whether you wanted it to be a generic method in a nongeneric type, or a nongeneric method in a generic type.
The positioning of type parameters and type arguments in Java is unintuitive IMO.
It means that the static create()
method has type parameters, like:
public static <Character, Integer> HashBiMap<Character, Integer> create() {..}
create()
is a generic method. Since it's static and has no parameters (hence no type inference), the only way you can tell it what the generic parameters are is by that strange-looking .<Character, Integer>
syntax.
Edit: This is actually not necessary in this specific case; the compiler can infer the generic types from the left-hand side. But it is sometimes necessary in other cases, such as this question.
Presumably it's the right-hand side (RHS) you think is weird
HashBiMap.<Character, Integer> create();
Usually, it's only necessary to use the type parameters on the LHS when calling a generic static method. But sometimes the static method does not infer the type parameters as you intended. In those cases you can also use the type parameters on the RHS in order to coerce the type parameters to whatever you intended. This is known as an explicit type parameter.
Here is an example of when type parameters are not inferred correctly (adapted from the excellent "Effective Java" book):
Given the static method
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)
you might think that you could do this:
Set<Integer> integers = ... ;
Set<Double> doubles = ... ;
Set<Number> numbers = union(integers, doubles);
If you try it you’ll get this error message:
Union.java:14: incompatible types
found : Set<Number & Comparable<? extends Number & Comparable<?>>>
required: Set<Number>
Set<Number> numbers = union(integers, doubles);
If the compiler doesn’t infer the type that you wish it had, you can tell it what type to use with an explicit type parameter. With the addition of this explicit type parameter, the program compiles cleanly:
Set<Number> numbers = Union.<Number>union(integers, doubles);
HashBiMap probably has a method
public static <K,V> HashBiMap<K,V> create(){...}
Using the syntax
HashBiMap<Character, Integer> charOcc = HashBiMap.<Character, Integer> create();
you are passing Character for K and Integer for V.