简体   繁体   中英

Java Generic method - what's the usage of extends keyword?

I don't understand the difference between these two code snippets.

What's the role of T extends List in the first example? Can I interpret it as "a method named see that you can pass List type or subtype of List to"? If yes, why not just use method 2?

1.

public <T extends List> void see(T n) {}

2.

public void see(List n) {}

In this example, I don't think it is useful.

But in this one :

public <T extends MyClass> T[] toArray(List<T> n) {
   ...
}

It gives you some type checking (I reused T in the return type).

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
//I gave a List<Integer> so it returns a Integer[]. No need to cast ! 
Integer[] myArray = toArray(list);

Whereas in this case :

//I don't know the generic type of the list so I return a Object[]
public Object[] toArray(List n) {
   ...
}

You will need to cast the result.

Note : To answer your question, here <T extends MyClass> only restrict the type of T to a subclass of MyClass .

"Bounded generic types" are normally used, to allow the parameter-types or return-types of a method/ or methods within a class to be inter-related.

Considering your example 1):

public <T extends List> void see(T n) {}

The generic type is bounded to be a subtype of List, so at the JVM level the compiled (raw) code & signature will be equivalent to example 2).

There are some subtle semantic differences in how "generic" and "raw" types are treated by the compiler, however. Conversion between "raw" and "generic" types typically a warning, as do unchecked generic type operations.

For code using generics properly, declaring List would (I understand) be preferable. Since there is no inter-relation between method parameters, the second style would be simpler.

My suggestion:

public void see (List<?> items) {}

The style in 1) makes more sense for inter-related parameters/ or result types. A couple of separate examples, showing more typical use:

public <T>  List<T> getChildren (T parent);
public <T>  List<T> listItems (T list1, T item2);
public <T extends List<?>>  T combineLists (T list1, T list2);

It is probably more common to declare T as the item parameter, and genericize collections on that, than to declare T as a "collection type".

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