简体   繁体   中英

how compiler infers the type in java generics

I have generic method which looks something like this.

public static <T> T addAndReturn(T element, Collection<T> collection){
    collection.add(element);
    return element;
}

When I call

String stringElement = "stringElement";
List<Object> objectList = new ArrayList<Object>();
Object theElement = addAndReturn(stringElement, objectList); 

It infers the type as object.

When I call

Object objectElement = new Object();
List<String> stringList = new ArrayList<String>();
Object theElement = addAndReturn(objectElement, stringList);

the compiler reports error.

What are the rules behind this?

In the first case, you are passing a List<Object> to the Collection<T> so T must be an Object type. A String stringElement is a sub-class of Object so this is allowed.

In the second case, you are passing a List<String> to the Collection<T> so T can only be String . As Object objectElement is not a String type this is not allowed.

You can't add an Object to a List<String> which seems reasonable.

Generics can be difficult to grasp, I recommend you read up on it carefully.

In your example, you have a type T which can be any one type. This type is "generic" in that it conforms to what type is put into it. So, when you pass an ArrayList<String> as the Collection<T> parameter, T becomes String in that instance. Therefore, the return type of the method becomes String .

Generics work on principle of Type inference. The compiler checks the type which from the generic class. Once the type is determined the compiler performs compile time type checking to make sure that all the type which are passed are correct. Generics also has type erasure at runtime but that is a different thing and we can skip it for this discussion.

To apply this principle on your questions: In the first case you are creating an object of type String which can be easily added to a ArrayList of type Object as String is a sub class of Object.

For the second example you are now doing the exact opposite. You are trying to save a Object class object in a reference of String class which is not allowed.

Thus if you notice the rules are exactly same even as that of a non generic code.

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