我可以将generics属性存储到对象的字段中

时间:2008-11-20 08:31:15

标签: java generics

假设以下类存根:

public class Foo<T> {
  private Class<T> type;

  public Foo<T> () {}
}

我可以将泛型类型T存储到构造函数中的字段type中,而不将构造函数的签名更改为“public Foo<T> (Class<T> type)”吗?

如果是,怎么样?如果不是,为什么?

type = T”似乎不起作用。

5 个答案:

答案 0 :(得分:9)

否 - 类型擦除意味着您必须在执行时提供某些内容。您可以提供TClass<T>的实例,但类本身只会将每次出现的T替换为Object

这种东西是Java的泛型与.NET中的最大缺点之一。 (另一方面,方差的故事更强 - 如果更混乱 - 在Java中比在.NET中。)

答案 1 :(得分:4)

正如thread中所说,

示例列表&lt;整数&gt;

list.get (index).getClass() 

为您提供存储在列表中的对象类型:

    列表为空时
  • 即使列表不为空,因为任何元素都可以是泛型类型参数的任何子类。

由于类型参数在编译时被擦除,它们在运行时不存在(对不起Jon,execution time):因此,您无法通过java中的反射获得泛型类型信息。

桌子上有更多reification的情况(Java 7?),并且会促进你的目标。

有人会希望一个输入T的坏类型会引发一个Cast异常,它会在执行时显示用于T的原始类型,但是唉,这也不起作用。

考虑以下测试类:

import java.util.ArrayList;

/**
 * @param <T>
 */
public class StoreGerenericTypeInField<T>
{

    private T myT = null;
    private ArrayList<T> list = new ArrayList<T>();

    private void setT(final T aT) { myT = aT; }
    /**
     * Attempt to do private strange initialization with T, in the hope to provoke a cast exception
     */
    public StoreGerenericTypeInField()
    {
        StringBuilder aFirstType = new StringBuilder();
        StringBuffer aSecondType = new StringBuffer();
        this.list.add((T)aFirstType);
        this.list.add((T)aSecondType);
        System.out.println(this.list.get(0).getClass().getName());
        System.out.println(this.list.get(1).getClass().getName());

        setT((T)aFirstType);
        System.out.println(this.myT.getClass().getName());
        setT((T)aSecondType);
        System.out.println(this.myT.getClass().getName());
    }
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        StoreGerenericTypeInField<Integer> s = new StoreGerenericTypeInField<Integer>();
    }
}

构造函数尝试将讨厌的东西存储到其T变量(或其List of T)中...并且一切运行顺利!?

打印:

java.lang.StringBuilder
java.lang.StringBuffer
java.lang.StringBuilder
java.lang.StringBuffer

类型擦除本身就是not to blame ...这是类型擦除(java新手)的组合 不安全的转换 (java旧版旧功能),这使得T在执行时真正无法实现(直到您真正尝试将其与“T”特定方法一起使用)

答案 2 :(得分:1)

那么,为什么不在课堂上有一个T实例呢?我的意思是,如果情况并非如此,T会给你带来什么?所以,如果你有T x,那么你可以使用x.GetType()。

答案 3 :(得分:-2)

确实

type = T.getClass();

工作?

答案 4 :(得分:-2)

你应该试试这个:

type = T.GetType();