【问题标题】:Instance of T (generic type) in JavaJava中T(泛型)的实例
【发布时间】: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&lt;String&gt;,只能写list instanceof List - 可以这样写。)
  • 泛型的整个想法是基于这样一个假设,即您更愿意编写public void foo(T bar),而不是采用Object 参数并在运行时使用instanceof 检查它。如果你想做后者,你真的不需要泛型。 (当然,这两者在技术上并非不相容,但从概念上讲,它们是两种不同的世界观,而且通常情况下,试图混合它们并没有什么好处。)

标签: java generics


【解决方案1】:

添加到 Java 的功能的提案进展缓慢,并且存在更高优先级的功能。 “他们还没有做到。”

直到 Java 1.5 才出现泛型,并且泛型类型在运行时丢失。

...

我的问题是,为什么它不是由编译器自动完成的?

对于存在任何泛型类型的每个类,编译器可以自动为每个构造函数添加一个(或多个,如果我有更多泛型类型)参数,并将这些值绑定到私有字段。

好吧,现在,您只是在问为什么 Java 不为运行时存储泛型类型信息。你要求物化。答案是 Java 的泛型是通过擦除实现的,你已经知道了。

是的,具体化是可能的,其他语言也可以。是的,也许 Java 有一天也会这样做。也许他们会以类似于您建议的方式进行操作。也可能不是。

Project Valhalla 最终可以解决此类问题。

【讨论】:

    猜你喜欢
    • 2023-04-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2020-06-20
    相关资源
    最近更新 更多