【发布时间】:2016-08-03 18:27:31
【问题描述】:
简而言之:为什么我不能用 Java 编写以下代码?
public class Foo<T> {
public void foo(Object bar) {
if (bar instanceof T) {
// todo
}
}
}
是的,我知道,泛型有点被入侵到 Java 中了。泛型直到 Java 1.5 才出现,并且泛型类型在运行时丢失。
我也知道,它有一些模式。例如:
public class Foo<T> {
Class<T> clazz;
public Foo(Class<T> clazz) {
this.clazz = clazz;
}
public void foo(Object bar) {
if (clazz.isInstance(bar)) {
// todo
}
}
}
我的问题是,为什么编译器不自动完成?
对于存在任何泛型类型的每个类,编译器可以自动为每个构造函数添加一个(或多个,如果我有更多泛型类型)参数,并将这些值绑定到私有字段。并且每次我写bar instanceof T它都可以编译为clazzOfGenericT.isInstance(bar)。
有什么原因,这个没有实现吗?
我不完全确定,这不会破坏向后兼容性* - 但是,新的 JVM 语言(如 Scala 或 Kotlin)为什么没有此功能?
*:恕我直言,可以做到,而不会破坏任何向后兼容性。
【问题讨论】:
-
它会破坏所有隐含依赖于
T的代码不是真实的东西,而且你可以随意地绕过它。 -
如果类型本身是通用的,就会有复杂性。例如列表
- >.
-
所有擦除的细节都绝对指定。
-
@PaulBoddington:没想到,谢谢! (而且,我不能写
list instanceof List<String>,只能写list instanceof List- 可以这样写。) -
泛型的整个想法是基于这样一个假设,即您更愿意编写
public void foo(T bar),而不是采用Object参数并在运行时使用instanceof检查它。如果你想做后者,你真的不需要泛型。 (当然,这两者在技术上并非不相容,但从概念上讲,它们是两种不同的世界观,而且通常情况下,试图混合它们并没有什么好处。)