代码之家  ›  专栏  ›  技术社区  ›  wutzebaer

扩展类型参数的内联类

  •  4
  • wutzebaer  · 技术社区  · 9 年前

    我想写一个快速而脏的助手类,它可以快速保存我的对象。因此,我使用OrmLite。

    我不想在类上添加注释,所以我尝试动态添加包装器,而不使用任何字节码库。

    <T> void save(T o) {
        @DatabaseTable
        class wrap extends T {
            @DatabaseField(generatedId = true)
            public Long id;
        }
    
        try {
            Dao<T, Long> d = (Dao<T, Long>) getClassDao(o.getClass());
            TableUtils.createTableIfNotExists(connectionSource, o.getClass());
            d.createOrUpdate(o);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    

    问题是 class wrap extends T -为什么不可能延长 T ?

    3 回复  |  直到 9 年前
        1
  •  3
  •   Lii bob    9 年前

    这是一个奇怪但有趣的问题!给出准确而详尽的答案很难。可能有很多不同的原因,但我认为以下一个是最重要的:

    只有一个版本的 save 将由编译器生成。 对于 class wrap extends T 计算参数 T 必须是不同的具体类才能使用 拯救 使用不同的类型,但泛型不是这样工作的。 拯救 只编译一次,并且在内部 拯救 T 是类型参数,而不是具体类型。(这与类型擦除有些关联,但不同于类型擦除,请参见下文。)

    另一个 原因是 type erasure 编译时间 另一方面,Java中的类 (例如,与C++相反)。因此,类的运行时表示不可能从泛型类型的编译时构造生成。

        2
  •  2
  •   Gelin Luo    9 年前

    <T> 是泛型类型,而不是真正的类。泛型类型是编译时的概念,它在运行时被删除,而类是运行时的东西,它有相应的字节码。不能声明泛型类型的子类 <T>

        3
  •  1
  •   Frank Puffer    9 年前

    因为T可能是最终的。期末班不能延期。

    至少这是禁止扩展泛型类型的逻辑原因。技术背景在其他答案中解释。