The JLS mentions in the type inference algorithm (§15.12.2):
It is possible that the process above yields an infinite type. This is permissible, and Java compilers must recognize such situations and represent them appropriately using cyclic data structures.
However, I'm unable to find an actual example where javac produces an infinite type. I think it ought to produce one in the following case:
<T> T pick(T a, T b) { ... }
pick("string", 3);
Both String and Integer are Comparable<themselve>, so their common supertype should be Comparable<? extends Comparable<? extends Comparable<? ...>>>
(infinite).
I can do:
Comparable<? extends Comparable<?>> x = pick("string", 3);
but then I tried:
Comparable<? extends Comparable<? extends Comparable<?>>> x = pick("string", 3);
and this doesn't compile. It seems that the recursion is aborted after 2 steps.
Do you know of any case to make Java actually produce an infinite type?
--
Edit: it seems that the above is a compiler bug. Reading the specification, let's see how the calculation of lub(String, Integer)
works out:
ST(String) = { String, Comparable<String>, Serializable, CharSequence, Object }
ST(Integer) = { Integer, Comparable<Integer>, Serializable, Number, Object }
EC = { Comparable, Serializable, Object }
MEC = { Comparable, Serializable }
Inv(Comparable) = { Comparable<String>, Comparable<Integer> }
lcta(String, Integer) = ? extends lub(String, Integer)
lci(Inv(Comparable)) = Comparable<? extends lub(String, Integer)>
lub(String, Integer) = Serializable & Comparable<? extends lub(String, Integer)>
So lub(String, Integer)
should be an infinite type. Javac seems to be wrong here. Maybe it doesn't implement infinite types after all?
Type inference is the idea that the compiler can figure out the static types for you so you don't have to type them. The general idea is that the compiler can infer the type based on surrounding context. In this case the HashMap contains a list of strings as indicated on the left-hand side.
Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
The target type of an expression is the data type that the Java compiler expects depending on where the expression appears. For instance, in the statement int a = b; , the target type is int - the expression, b , should have a type of int (or something convertible to it), because its context requires that.
The following code sends javac to an infinite loop. Presumably, it tries to build an infinite type, but does not manage to represent it as a finite cyclic data structure.
interface I<T> {}
interface A<T> extends I<A<A<T>>>{}
abstract class X {
abstract <T> T foo(T x, T y);
void bar(A<Integer> x, A<String> y){
foo(x, y);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With