类型安全:未经检查的强制转换和泛型

时间:2011-03-10 04:32:29

标签: java generics map casting type-safety

我有一张非常简单的地图

private Map<String,T> map = Collections.synchronizedSortedMap(new TreeMap<String,T>());

我想定义以下方法

public T[] values(){
    return (T[])map.values().toArray();
}

显然,我最终会遇到一个未经检查的演员问题...我的问题是我无法调用toArray(new T[size])

我应该怎么做才能避免这种警告(不使用@SuppressedWarning)

由于

4 个答案:

答案 0 :(得分:4)

避免使用数组。返回List<T>

数组是必要的基本构建块,但它们在类型系统中非常奇怪。最好在API中避免使用它们。几乎任何地方都可以用ArrayList替换数组。表现相同。

答案 1 :(得分:0)

我能想到的最好的事情是为你的类创建一个构造函数,它接受一个T类型的数组(即一个T []参数)。您的类的用户应该提供一个零大小的数组。然后,您可以使用此数组进行toArray(T [])调用。

答案 2 :(得分:0)

  

我应该怎么做才能避免这种警告   (没有使用@SuppressedWarning)

这个警告是你应该担心的最后一件事。更大的问题是当它返回给需要具有特定类的数组的人时,这将会导致ClassCastException崩溃。

因为Java中的数组在运行时包含对其组件类的引用,所以在不知道类的情况下构造这样的数组是不可能的。让用户传入某个内容会让您获得类T的类对象,或者您只需要返回Object[]

答案 3 :(得分:0)

要获取泛型类型的数组,必须将Class对象传递给方法,否则它将返回Object []类型的数组。

public T[] values(Class<T> cl){
    return (T[])map.values().toArray((T[])Array.newInstance(cl,0));
}

您仍需要对此代码使用SuppressdWarning,但它不会在运行时抛出。此外,如果您需要它来实现collection.values(),您必须在您的ctor中传递该类。数组和泛型只是混合不好,这就是你更喜欢使用集合的原因。