OiO.lk Blog java Type inference error when generic class constructor builds an instance of another generic class with bounded type
java

Type inference error when generic class constructor builds an instance of another generic class with bounded type


When type parameter is bounded (T extends Comparable<? super T>), I encounter a type inference problem using <> to let the compiler infer the type in the following example:

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class InferTypeArgApp {
    static class ACollection<E extends Comparable<? super E>> {
    // static class ACollection<E> {  // <-- If E isn't bounded, BCollection can use <>
        private Set<E> mySet;

        ACollection(Comparator<? super E> comparator) {
            mySet = new TreeSet<>(comparator);
        }
    }

    static class BCollection<E extends Comparable<? super E>> {
        private ACollection<E> myACollection;

        BCollection(Comparator<? super E> comparator) {
            myACollection = new ACollection<>(comparator);
            //              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- Cannot infer type
            //                                                arguments for
            //                                                ACollection<>Java(16778094)
            //
            // myACollection = new ACollection<E>(comparator);  // <-- This works
        }
    }

    public static void main(String[] args) {
        ACollection<Integer> col = new ACollection<>(null); // <-- Java manages to
                                                            //     implicitly infer
                                                            //     the type here
    }
}

If I declare ACollection as class ACollection<E extends Comparable<? super E>> then I get the type argument inference error. However, if it’s declared as class ACollection<E> then there is no error.

The way I see it, Java compiler has enough information to infer that ACollection I initialize in BCollection constructor has type argument E regardless of whether ACollection type argument extends anything.

Why is there a type inference error?

For completeness, here is the full compilation error which didn’t clarify anything for me but hopefully someone can parse it:

$ /usr/local/java/jdk/bin/javac -Xdiags:verbose InferTypeArgApp.java
InferTypeArgApp.java:20: error: cannot infer type arguments for ACollection<>
            myACollection = new ACollection<>(comparator);
                            ^
  reason: cannot infer type-variable(s) E#1
    (argument mismatch; Comparator<CAP#1> cannot be converted to Comparator<? super E#3>)
  where E#1,E#2,E#3 are type-variables:
    E#1 extends Comparable<? super E#1> declared in class ACollection
    E#2 extends Comparable<? super E#2> declared in class BCollection
    E#3 extends CAP#1,Comparable<? super E#3>
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object super: E#2 from capture of ? super E#2
1 error



You need to sign in to view this answers

Exit mobile version