yapkm01
yapkm01

Reputation: 3775

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.

}

Upvotes: 1

Views: 103

Answers (5)

Chris Hannon
Chris Hannon

Reputation: 4134

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

Upvotes: 1

Satya
Satya

Reputation: 8346

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

Upvotes: 0

irreputable
irreputable

Reputation: 45433

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.

Upvotes: 1

dinidu
dinidu

Reputation: 183

    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.

Upvotes: 0

Brett Walker
Brett Walker

Reputation: 3576

I would say that the inferred type would be Object

Upvotes: 0

Related Questions