如何编写一个方法,该方法采用某种T
类型的参数(Iterable
的实例),以及参数Class<E>
,并返回{{1} }?
T<E>
我想这样用:
public static <...> ... checkedCast(T iterable, Class<E> clazz) {
// Check elements and throw ClassCastException if invalid
@SupressWarning("checked")
... cast = (...)iterable;
return cast;
}
我知道我可以使用覆盖执行此操作,但这需要我为每种类型编写覆盖:
// This should compile
ArrayList<?> a = ...;
ArrayList<String> b = checkedCast(a, String.class);
// So should this
HashSet<Number> c = ...;
Set<Integer> d = checkedCast(c, Integer.class);
// This shouldn't compile
b = checkedCast(a, Integer.class);
// This shouldn't compile
b = checkedCast(c, Integer.class);
// This should throw ClassCastException
checkedCast(a, Integer.class);
答案 0 :(得分:2)
Java类型系统的泛型扩展的一个缺点是,我们如何以单数形式考虑类型并不会扩展到我们如何看待复数类型。
简而言之,通用类型的集合无法安全地投射。构建一个新列表,拉出每个类型并单独检查它,然后返回新列表。如果您忽视此警告,我会指示某人做类似
的事情List<Customer> customers = new ArrayList<>();
customers.add(new Customer(...));
List<Object> customerObjects = checkCast(customers, Object.class);
customerObjects.add(new Order(...));
你被警告了。
答案 1 :(得分:0)
看看这是否适合您。但是,如果您能够更详细地描述为什么需要这样的方法,人们可以更好地帮助您。
public static
<InputElement, OutputElement extends InputElement,
InputContainer extends Iterable<InputElement>,
OutputContainer extends Iterable<OutputElement>>
OutputContainer checkedCast(InputContainer iterable,
Class<OutputElement> clazz) {
@SuppressWarnings("unchecked")
OutputContainer output = (OutputContainer) iterable;
return output;
}
答案 2 :(得分:0)
这适用于您的要求 - 除了抛出ClassCastException(如果您真的想要这种行为,您可以自己将它包含在checkedCast方法中):
import java.util.*;
public class CheckedCast {
public static <GenB, GenA extends GenB, CollA extends List<GenA>> List<GenB> checkedCast(CollA iterable, Class<GenB> clazz){
return (List<GenB>)iterable;
}
public static <GenB, GenA extends GenB, CollA extends Set<GenA>> Set<GenB> checkedCast(CollA iterable, Class<GenB> clazz){
return (Set<GenB>)iterable;
}
static class One {}
static class Two extends One {}
static class Three {}
public static void main(String[] args) {
ArrayList<Two> test1 = new ArrayList<Two>();
List<One> test2 = checkedCast(test1, One.class);
// Shouldn't compile...
ArrayList<One> aa = checkedCast(test2, One.class); // output is ArrayList
List<Two> bb = checkedCast(test2, Three.class); // Three is not superClass of Two
ArrayList cc = checkedCast(new HashSet(), Integer.class); // Set cannot become List
ArrayList<One> dd = checkedCast(new LinkedList<One>(), One.class); // ArrayList is not superClass of List
}
}
更新以匹配新要求: ArrayList xs = checkedCast(new HashSet(),Integer.class) - 不应编译
更新:更新为断言返回的Collection泛型类型扩展了输入Collection的泛型类型。