Java中通用数组最简单的替代方法是什么?

时间:2008-12-20 23:45:15

标签: java arrays generics

假设我有这个:

class test<T>
{
    private T[] elements;
    private int size;
    public test(int size)
    {
        this.size = size;
        elements = new T[this.size];
    }
}

似乎这是不可能的,因为编译器在尝试替换泛型代码或其他内容时不知道要调用的构造函数。我想知道的是,我该怎么做呢?我认为这是可能的,因为它在C ++中是多么容易完成。

编辑:对不起,我忘记了元素声明中的[]。

7 个答案:

答案 0 :(得分:13)

问题在于,由于编译器将泛型类型参数T转换为Object(它的名称为 type erasure ),因此实际上创建了一个{{1}数组1}}。您可以做的是为函数提供Object

Class<T>

您可以在此处找到更好的exlanation:Angelika Langer - Can I create an array whose component type is a type parameter?

答案 1 :(得分:8)

通用数组的最简单替代方法是使用列表。

答案 2 :(得分:3)

我倾向于避免使用基本数组并尽可能使用ArrayLists(或类似的Lists),原因有很多。最重要的两个是:

  1. 我不需要光头阵列的语义。括号表示法(即指针算术的简写)并没有什么能让我的生活更轻松。

  2. 如果我使用Lists,我会根据需要设置自己使用更复杂的并发启用结构。例如,使用CopyOnWriteArrayList替换ArrayList很容易。

  3. 因此,使用通用ArrayList编写示例将如下所示:

    class test<T> {
        /** It's not strictly necessary to make this a List vs. an ArrayList
            You decide what interface you really need to expose internally. */
        private List<T> elements;
        /** This parameter isn't necessary with a List.  You can always call the
            size() method instead. */
        private int size;
        public test(int size) {
            this.size = size;
            elements = new ArrayList<T>();
            // Note that the next line isn't strictly necessary.
            // An ArrayList can be dynamically resized without any real effort on your part.
            elements.ensureCapacity(size); 
        }
    }
    

答案 3 :(得分:2)

有两种解决方案不需要传入类对象。在这两个中我都假设因为它是一个私有变量,所以你是唯一一个把东西放入其中的人,而外界却没有看到它。

一种是使用普通的Object数组Object[]。缺点是你将失去泛型的好处,你将不得不抛出一些东西,这使得代码更加丑陋。但是因为你是唯一一个把东西放进去的人,所以演员应该总是安全的。外面不需要知道发生了什么。

其他选择是一种黑客攻击。您创建Object[],然后将其“投射”到T[]。从技术上讲,这是非法的,因为Object[]T[]是不同的运行时类型,前者不能转换为后者。但是只要你不将数组传递出类(例如返回它或其他东西),那么它就不会引起任何问题,因为T[]无论如何都会被删除到Object[],并且实际上没有演员表演。然后,您可以在类中获得泛型的好处,以便更轻松地编码,但是您必须非常小心,不要将该数组传递给实际需要T[]的任何人,因为它不是。

答案 4 :(得分:0)

我可能错了,但你的声明似乎很奇怪,你不应该:

private T[] elements;

答案 5 :(得分:0)

尺寸字段确实显得多余。你可以只使用elements.length而不是size。

class Test<T> {
    private final T[] elements;
    public test(int size) {
        elements = (T[]) new Object[size];
    }
}

或者您可以使用ArrayList替换Test类。即完全放弃课程。

答案 6 :(得分:0)

还要看这段代码:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

它将任何类型对象的列表转换为相同类型的数组。