在 Java 中的字段中存储类泛型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/911483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:19:37  来源:igfitidea点击:

Store class generic in field in Java

javagenerics

提问by David Berger

Is there any way to store the generic parameter type passed in at construction to a parameter. My goal:

有什么方法可以将构造时传入的泛型参数类型存储到参数中。我的目标:

class generic<T> {
    Class<T> type;
    public generic() {
        super();
        this.type = //Something that gets class from T
    }
}

What I'm currently doing is this:

我目前正在做的是:

class generic<T> {
    Class<T> type;
    public generic(Class<T> type) {
        super();
        this.type = type;
    }
}

It seems silly to have to specify the class twice, but I'm not sure of how else to do it. I think this might be possible with reflection, but I haven't investigated that yet. Is there a more straightforward way? If not (as an aside) why the information loss?

必须两次指定类似乎很愚蠢,但我不知道还能怎么做。我认为这可能通过反射实现,但我还没有对此进行调查。有没有更直接的方法?如果不是(顺便说一句)为什么信息丢失?

回答by bruno conde

Because Java generics are implemented with Type Erasure

因为 Java 泛型是用Type Erasure 实现的

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

当泛型类型被实例化时,编译器通过一种称为类型擦除的技术来转换这些类型——编译器删除与类或方法中的类型参数和类型参数相关的所有信息的过程。类型擦除使使用泛型的 Java 应用程序能够保持与 Java 库和在泛型之前创建的应用程序的二进制兼容性。

回答by Tom Hawtin - tackline

If you use a static creation method with type inference instead of the constructor, then the type does not need to be specified twice.

如果您使用带有类型推断的静态创建方法而不是构造函数,则不需要两次指定类型。

final class Generic<T> {
    private final Class<T> type;
    private Generic(Class<T> type) {
        super();
        if (type == null) {
            throw new NullPointerException();
        }
        this.type = type;
    }
    public static <T> Generic<T> newInstance(Class<T> clazz) {
        return new Generic<T>(clazz);
    }
}
...
    someFunction(Generic.newInstance(SomeType.class));

Of course, if you want to store the result in a variable, you are probably going to repeat the type anyway!

当然,如果您想将结果存储在变量中,无论如何您可能会重复该类型!

回答by pgb

I think you can't do it because of type erasure.

我认为你不能这样做,因为类型擦除

回答by Yishai

They type is not preserved at runtime, so you cannot take it as a parameter. Generics in java are strictly a compile-time concept (for backwards compatability reasons). This is called Type Erasure.

它们的类型不会在运行时保留,因此您不能将其作为参数。java 中的泛型严格来说是一个编译时概念(出于向后兼容性的原因)。这称为类型擦除

One of the reasons the class object takes a type parameter is precisely to work around this problem, so you can take the class object to represent the type programatically.

类对象采用类型参数的原因之一正是为了解决这个问题,因此您可以采用类对象以编程方式表示类型。