为什么 Java 运行时不允许泛型类型查找?

发布于 2024-12-08 16:43:40 字数 1557 浏览 0 评论 0原文

我想看看是否有可能在 Java 运行时获取泛型类的对象类型。

示例:

public class Member<T> {

    private T id;
    private T complexityLevel;

    // constructor
    public Member(T id, T complexityLevel) {
        this.id = id;
        this.complexityLevel = complexityLevel;
    }

    // getters and setters goes here
}

测试..

public class TestDrive {

    public static void main(String[] args) {
        Member<String> memberString = new Member<String>("1", "100");
        Member<Integer> memberInteger = new Member<Integer>(1, 100);
        Member<Double> memberDouble = new Member<Double>(1.0, 100.00);

        List<Member<?>> members = new ArrayList<>();
        members.add(memberString);
        members.add(memberInteger);
        members.add(memberDouble);

        for (Member<?> aMember : members) {
            if (aMember.getClass().isInstance(String.class))
                System.out.printf("String member is found with id: " + aMember.getId());
            else if (aMember.getClass().isInstance(Integer.class))
                System.out.printf("Integer member is found with id: " + aMember.getId());
            else if (aMember.getClass().isInstance(Double.class))
                System.out.printf("Double member is found with id: " + aMember.getId());
        }
    }
}

是否可以获得包装类(StringIntegerDouble< /code> 等)对于运行时 Member 类的对象?

I am trying to see if it possible to get object type for a generic class at run-time in Java.

Example:

public class Member<T> {

    private T id;
    private T complexityLevel;

    // constructor
    public Member(T id, T complexityLevel) {
        this.id = id;
        this.complexityLevel = complexityLevel;
    }

    // getters and setters goes here
}

Testing..

public class TestDrive {

    public static void main(String[] args) {
        Member<String> memberString = new Member<String>("1", "100");
        Member<Integer> memberInteger = new Member<Integer>(1, 100);
        Member<Double> memberDouble = new Member<Double>(1.0, 100.00);

        List<Member<?>> members = new ArrayList<>();
        members.add(memberString);
        members.add(memberInteger);
        members.add(memberDouble);

        for (Member<?> aMember : members) {
            if (aMember.getClass().isInstance(String.class))
                System.out.printf("String member is found with id: " + aMember.getId());
            else if (aMember.getClass().isInstance(Integer.class))
                System.out.printf("Integer member is found with id: " + aMember.getId());
            else if (aMember.getClass().isInstance(Double.class))
                System.out.printf("Double member is found with id: " + aMember.getId());
        }
    }
}

Is it possible to get wrapper classes (String, Integer, Double etc) for objects of Member class at run-time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱娆 2024-12-15 16:43:40

由于类型擦除,您无法在运行时确定泛型类型。为了在擦除后保留此信息,Member 需要在其构造函数中获取一个 Class 对象并保留它:

public class Member<T> {

public final Class<T> type;

private T id;
private T complexityLevel;

//constructor   
public Member(T id, T complexityLevel, Class<T> type) {
   id = id;
   this.complexityLevel = complexityLevel;
   this.type = type;
}

然后:

Member<String> mString = new Member<String>("id1", "High", String.class);

...

System.out.println(mString.type.getName());

或者,如果保证 id 永远不会为 null,您可以使用反射来检索表示其类型的 Class 对象:

System.out.println(mString.getId().getClass().getName());

当然 getClass() 将返回一个。因此,如果 id 实际上是 T 的子类,您将获得该类的名称而不是 T 的名称。

You can't determine generic types at runtime due to type erasure. In order for this information to be preserved after erasure, Member<T> would need to take a Class<T> object in its contructor and hold onto it:

public class Member<T> {

public final Class<T> type;

private T id;
private T complexityLevel;

//constructor   
public Member(T id, T complexityLevel, Class<T> type) {
   id = id;
   this.complexityLevel = complexityLevel;
   this.type = type;
}

Then later:

Member<String> mString = new Member<String>("id1", "High", String.class);

...

System.out.println(mString.type.getName());

Alternatively, if id is guaranteed never to be null, you could use reflection to retrieve the Class object representing its type:

System.out.println(mString.getId().getClass().getName());

Of course getClass() will return a Class<? extends T>. So if id is in fact a subclass of T, you're going to get the name of that class rather than the name of T.

み格子的夏天 2024-12-15 16:43:40

此信息(泛型类型 T)在编译期间被删除(类型擦除)。

使用 超级类型标记 是一种中等痛苦的技术,可以应用于此处。 Guice 的 TypeLiteral 就是一个示例。

此外,String 和 Integer 不是原始类型。 “int”是一个原语。

This information (the generic type T) is stripped out during compilation (type erasure).

Using super type tokens is a moderately painful technique that can apply here. Guice's TypeLiteral is an example of this.

Also, String and Integer are not primitive types. "int" is a primitive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文