In my project, the external API we 开发者_运维问答used is not genericfied, so there's a class called ItemList
which is an implementation of java.util.List
, it holds a list of Item
objects. however in our new code we express this as List<Item>
, I want to write a method that can takes both ItemList
and List<Item>
,
I tried this kind of signature:
public static void readList(List<?> list) {}
it works fine, but the problem is there is a cast from Object
to Item
inside this method, which is used when the argument is ItemList
, and not necessary for List<Item>
, is there a better way to do this?
If ItemList
is an implementation of List
, and if you know it contains Item
instances, just cast it to List<Item>
. You'll get a type safety warning, but it's not less safe than casting each element of the ItemList
to Item
.
Can you write your new API to handle List<Item>
so it is clean moving forward, and then provide a static conversion method to act as an adapter for the legacy uses List<Item> asList(ItemList itemList)
? This way you isolate where the ugly unchecked conversion happens.
What about providing two methods - one for each parameter type. At least you only have only one type safety warning in a known place that has been discussed and accepted:
public static void readList(List<Item> list) {
// do something
}
@SuppressWarnings("unchecked")
public static void readItemList(List<?> list) {
readList((List<Item>)list); // Type safety warning tucked away in here
}
Although you don't have type safety, the name of the method readItemList
is at least a strong hint to coders of the list type they are expected to be passing in.
If I am reading the API correctly, java.lang.Class:getTypeParameters() looks promising. Try:
if(list.getClass().getTypeParameters().length == 0) {
// Code for non-generic
} else {
// Genericized
}
精彩评论