Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Java fail to deduce the generic type parameter when using the ternary operator (`?`)?

Tags:

java

generics

Why is the compiler able to determine the generic type parameter for an assignment, but not for the ternary operator (?)?

I have a question regarding the compiler being able to deduce the generic type parameter in case of a "direct" assignment but failing in case of the ternary operator (?). My examples uses Guava's Optional class, to make my point, but I think the underlying issue is generic and not restricted to Optional.

Optional has a generic function absent():

public static <T> Optional<T> absent();

and I can assign an Optional<T> to an Optional<Double>:

// no compiler error
final Optional<Double> o1 = Optional.absent();

How does the compiler realize, that T should be Double in this case. Because when using the ternary operator (?), I need to tell the compiler specifically to us Integer as the generic parameter

// Type mismatch: cannot convert from Optional<capture#1-of ? extends Object> to Optional<Integer>
final Optional<Integer> o2 = true
    ? Optional.of(42)
    : Optional.<Integer>absent();

otherwise I get the following error

Type mismatch: cannot convert from Optional<capture#1-of ? extends Object> to Optional<Integer>

Why is there a difference between a "direct" assignement and using the ternary operator? Or is there something else I am missing?

like image 429
Micha Wiedenmann Avatar asked Jul 08 '13 09:07

Micha Wiedenmann


People also ask

Which types can be used as arguments of a generic type?

The actual type arguments of a generic type are. reference types, wildcards, or. parameterized types (i.e. instantiations of other generic types).

Are generics type differ based on their type arguments?

A class interface or a method that operates on a parameterized type is called generic, like generic class or generic method, and generics only works with objects. And their type differs based on their type arguments.

Is generic type parameter?

Generic MethodsA type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.


1 Answers

Because of type inference rules, it appears the ternary expression does not infer the type parameter from the return type. The type of the ternary expression depends on the types of its operands. But one of the operands has undetermined type parameter (Optional.absent()). At that point the ternary expression still does not have a type, so it cannot influence the type parameter.

You can also look into this bug report for more information. You can look into the JLS .

The type of the conditional expression is the result of applying capture conversion (??5.1.10) to lub(T1, T2)

Here what the JLS says :

If the method result occurs in a context where it will be subject to assignment conversion to a type S, then let R be the declared result type of the method, and let R' = R[T1 = B(T1) ... Tn = B(Tn)] where B(Ti) is the type inferred for Ti in the previous section, or Ti if no type was inferred.

like image 146
AllTooSir Avatar answered Nov 15 '22 23:11

AllTooSir