【问题标题】:Type erasure: Java vs C# [duplicate]类型擦除:Java vs C# [重复]
【发布时间】:2023-04-07 11:34:01
【问题描述】:

可能重复:
C# vs Java generics

Java 使用 类型擦除C# 在运行时保留类型信息,这种设计在语言行为上的实际区别是什么?

【问题讨论】:

标签: c# java types type-inference type-erasure


【解决方案1】:

类型擦除存在很多问题。它带回了不好的回忆。我从 1.6 开始就没有使用过 Java,所以这可能已经过时了,但我记得一些事情:

  1. 你不能创建一个新的 T(或者做任何需要知道 T 实际是什么类型的事情)
  2. 通用列表无法创建 T 数组
  3. 不能在 Java 的泛型中使用 int、float 等
    1. 这会影响性能和内存,因为您必须始终使用堆版本(整数等)
  4. 您不能实现具有两个不同 T 的通用接口,例如class c implements IComparable<MyClass>, IComparable<MyOtherClass> 是不可能的。
    1. 更实际的是,您不能重载具有不同泛型类型的方法,例如通过接收List<T1>List<T2> 等等。例如,Java -- How to deal with type erasure in constructors?
  5. 一切都通过铸造和拳击完成

【讨论】:

    【解决方案2】:

    这是一个只有在运行时保留类型信息才可能实现的示例:

    public string DoSomething<T>()
    {
        return typeof(T).Name;
    }
    

    你可以在 Java 中获得的最接近的是:

    public <T> string DoSomething(Class<T> theClass)
    {
        return theClass.getName();
    }
    

    【讨论】:

      【解决方案3】:

      由于类型擦除而在 Java 中发生的事情是创建称为“桥接方法”的合成方法。

      这通常发生在 Java 尝试编译扩展参数化类或实现参数化接口的类或接口时。在这种情况下,Java 编译器可能需要创建一个合成方法(桥接方法)作为类型擦除过程的一部分,该过程出现在堆栈跟踪中。

      编译器这样做是为了在类型擦除过程之后保留泛型类型的多态性。

      Java 的文档有an example

      【讨论】:

        猜你喜欢
        • 2020-07-27
        • 1970-01-01
        • 1970-01-01
        • 2016-03-31
        • 1970-01-01
        • 1970-01-01
        • 2012-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多