简体   繁体   中英

What type parameter will be used if I call a generic method with a raw type as argument?

I'm just curious what's the generated inferred T type when passing a raw to a T type. It does compile but with a warning.

public class GenericMethodInference {

    static <T> void test5(List<T t>){} // clause (5)

    public static void main(String [] args) {

    List e = new ArrayList<Integer>();
    test5(e);  // clause (6) // ok but with warning.

}

This is done for backward compatibility. Before generics,

static void test5(List t){}

List e = ...;
test5(e);  

When generics was introduced, they need to generify List and methods like test5() , without asking all usages like test5(e) to be rewritten and recompiled. So test5(e) must still be valid.

This is achieved by relaxing type inference rules and method signature matching rules.

Inference: List << List<T> this can't hold in the subtyping sense; however inference rules just ignore it; T has no constraints, and simply picked to be Object

Method signature: List e is is not subtype of the method parameter type List<Object> , however it is acceptable by "method invocation conversion", which allows "unchecked conversion" from List to List<Whatever> ; the "unchecked conversion" triggers the mandatory compiler warning.


This is only of historical interest; no programmer today should care. Since obviously there's no way for List to be a subtype of List<T> whatever T is, we should practically treat it as error, and never write code like that (even though it compiles). A List<?> e would work.

Assigning a raw type to a generic type will assume no generic constraint (which will default to Object) but remove any compile-time type safety guarantees that might otherwise have existed.

But you cannot assign a raw to a List <Object> since it has been erased

It sounds like there is a fundamental misunderstanding of type erasure here. The raw type is the end result of a generic type . You specified List<Integer> , the compiler verifies against that type information and then removes the <Integer> portion of that, inserting casts to Integer as appropriate from actions against the raw type of List.

That means that these two retrieval operations are exactly the same.

List<Integer> integerList = new ArrayList<Integer>();
integerList.add(5);

Integer i = integerList.get(0); 
Integer ii = (Integer)((List)integerList).get(0);

For example, the following is legal. This only gives a warning (instead of causing a compiler error or runtime error) because we're acting on Object and are still within the appropriate bounds of the contained type.

List<Object> objects = (List)integerList;
Object value = objects.get(0);
System.out.println(value);

It will print out 5. Where the type system helps is if you try to do something like this.

List<String> badStringList = integerList;

It will give you a compiler error stating that there is a type mismatch. Using the raw type directly, however, will throw all of that type safety away and rely solely on your judgement for the correct types that should be used. This allows you to easily shoot yourself in the foot if you get it wrong.

List<String> badStringList = (List)integerList;
String badValue = badStringList.get(0); //ClassCastException is thrown at runtime

我会说推断的类型是Object

    public class GenericMethodInference {

    static <T> void test5(List<T> xx) {
        System.out.println(xx.getClass());  //class java.util.ArrayList
        System.out.println(xx.get(0).getClass()); //class java.lang.Integer
        System.out.println(xx.get(1).getClass()); //class java.lang.String
    } // clause (5)

    public static void main(String[] args) {

        List e = new ArrayList<Long>();
        e.add(1);
        e.add("2");
        test5(e); // clause (6) // ok but with warning.
    }
}

This confirms that the type inferred is Object type.

T is a generic one. It can accept any object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM