我认为这里肯定有些微妙的事情我不知道。考虑以下:
public class Foo<T> {
private T[] a = (T[]) new Object[5];
public Foo() {
// Add some elements to a
}
public T[] getA() {
return a;
}
}
假设您的main方法包含以下内容:
Foo<Double> f = new Foo<Double>();
Double[] d = f.getA();
您将收到一条无法转换为CastClassException
的消息。java.lang.Object``java.lang.Double
谁能告诉我为什么?我的理解ClassCastException
是,当您尝试将对象强制转换为无法强制转换的类型时,会抛出该错误。也就是说,对于不是实例的子类(引用文档)。例如:
Object o = new Double(3.);
Double d = (Double) o; // Working cast
String s = (String) o; // ClassCastException
看来我可以做到。如果a
只是一个T
而不是一个数组T[]
,我们可以a
毫无问题地获取并强制转换它。为什么数组会破坏这一点?
谢谢。
Foo<Double> f = new Foo<Double>();
使用泛型类Foo的此版本时,然后对于成员变量a
,编译器实质上采用以下行:
private T[] a = (T[]) new Object[5];
和更换T
用Double
得到这个:
private Double[] a = (Double[]) new Object[5];
您不能从Object转换为Double,因此不能转换为ClassCastException。
更新和说明: 实际上,在运行一些测试代码之后,ClassCastException比这更微妙。例如,这个main方法可以正常工作,没有任何异常:
public static void main(String[] args) {
Foo<Double> f = new Foo<Double>();
System.out.println(f.getA());
}
当您尝试分配f.getA()
给以下类型的引用时,会发生此问题Double[]
:
public static void main(String[] args) {
Foo<Double> f = new Foo<Double>();
Double[] a2 = f.getA(); // throws ClassCastException
System.out.println(a2);
}
这是因为有关成员变量的类型信息a
在运行时会被删除。泛型仅在 编译时 提供类型安全性(我在最初的文章中以某种方式忽略了这一点)。所以问题不在于
private T[] a = (T[]) new Object[5];
因为在运行时这段代码确实
private Object[] a = new Object[5];
当方法的结果(getA()
在运行时实际上返回Object[]
)被分配给类型的引用时,就会发生问题,Double[]
因为无法将对象强制转换为Double,因此该语句引发ClassCastException。
更新2 :回答您的最后一个问题“为什么数组会破坏它?”
答案是因为语言规范不支持通用数组创建。有关更多信息,请参见此论坛帖子
-为了向后兼容,在运行时对T的类型一无所知。
问题内容: 我的任务是用Java编写哈希表,该哈希表必须适用于任何数据类型。我正在编写的代码规则如下:-哈希表必须具有一个数组作为基础数据结构,其大小在构造对象时确定- 发生冲突时,应该放置碰撞的元素链接列表,该列表包含哈希表中该索引(键)处的所有元素 因此,对于基础数据类型,我做了一个LinkedList类型的数组(自定义,不是Java API LinkedList)。 当然,问题是实例化此数组
问题内容: 我正在尝试使用JAXB的自省功能来编组和分解所有使用JAXB批注标记的现有域对象。大多数事情都按预期运行,但是要获得一个相当简单的类进行序列化,我会遇到很多麻烦。此类在许多bean上用作@XmlElement,看起来像: 我尝试执行以下操作,但没有成功,JAXB仍然对接口Comparable感到愤怒。 将Range和DoubleRange都用作bean getter的返回类型会产生如下
在有效Java(第2版)第25项的最后一段中说:
问题内容: 因此,我正在开发这个通用的HashTable类,并且希望将其通用地用于任何数量的传入类型,并且我还想将内部存储数组初始化为LinkedList的数组(出于冲突目的),其中为确保类型安全,每个LinkedList都被预先指定为HashTable类中的泛型类型。我该怎么做?以下代码最能阐明我的意图,但当然不会编译。 问题答案: Java中的泛型不允许创建具有泛型类型的数组。您可以将数组转换
问题内容: 我正在尝试创建一个泛型类型的数组。我收到错误消息: 我很困惑。任何线索为什么会这样。 问题答案: 其背后的原因是,您不能创建通用或参数化类型的数组,而只能 创建可验证的 类型(即可以在运行时推断出的类型)。 尽管可以将此类数组类型 声明 为变量或方法参数。这有点不合逻辑,但这就是Java的样子。 Java泛型和集合在第6章中广泛讨论了此问题和相关问题。
我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。