Java 中的通用数组 [英] Generic arrays in Java

查看:37
本文介绍了Java 中的通用数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我一直在用 google 搜索网络,但似乎找不到任何解决我问题的方法.我找到了很多解决方案,但没有一个适合.

OK, I've been google'ing the web, and I just can't seem to find any solution to my problem. I found lots of solutions, just not any that fit.

我需要创建一个泛型数组.但是泛型类型本身扩展了 Comparable.当我尝试以下操作时:

I need to create an array of generics. But the generic type itself extends Comparable. When I try the following:

public class Hash<T extends Comparable<String>> {
    private T[] hashTable;
    private int tableSize;

    Hash(int records, double load) {
        tableSize = (int)(records / loadFactor);
        tableSize = findNextPrime(tableSize);
        hashTable = (T[])(new Object[tableSize]);  //Error: Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
    }
}

问题是不能将 Object 转换为扩展 Comparable 的泛型.有没有办法解决这个问题?

The problem is that the Object cannot be cast as a generic that extends Comparable. Is there a way around this?

推荐答案

泛型和数组基本上不能混用.简短的回答是您可以解决这个问题.更长的答案是你可能不应该,我会解释原因.

Generics and arrays don't mix, basically. The short answer is that you can work around this problem. The longer answer is that you probably shouldn't and I'll explain why.

您可以使用 Array.newInstance() 像这样:

You could use Array.newInstance() like this:

private Comparable[] hashtable;

...

hashtable = (Comparable[])Array.newInstance(Comparable.class, tableSize);

但您不能创建参数化类型的数组.

but you can't create an array of your parameterized type.

数组是协变的.这意味着它们在运行时保留其元素的类型.Java 的泛型不是.他们使用类型擦除来基本上掩盖正在进行的隐式转换.理解这一点很重要.

Arrays are covariant. That means they retain the type of their elements at runtime. Java's generics are not. They use type erasure to basically mask the implicit casting that is going on. It's important to understand that.

因此,当您创建 Object 数组时,您不能将其强制转换为 Comparable 数组(或任何其他类型),因为这是不正确的.

So when you create an Object array you can't cast it to, say, a Comparable array (or any other type) because that is not correct.

举个例子.对于泛型,这是完全合法的:

To give you an example. With generics this is perfectly legal:

List<String> list = new ArrayList<String>();
List<Integer> list2 = (List<Integer>)list;
list.add(3);

这也是你不能这样做的原因:

It's also why you can't do this:

public <T> T newInstance(T t) {
  return new T(); // error!
}

即在运行时不知道 T 的类.这就是为什么上面的代码更常写成:

ie at runtime there is no knowledge of T's class. This is why the above code is more often written as:

public <T> T newInstance(T t, Class<T> clazz) {
  return clazz.newInstance();
}

因为它们不是泛型参数的运行时类型.但是对于数组:

because their is no runtime type for the generic argument. But with arrays:

String arr[] = new String[10];
Integer arr2[] = (Integer[])arr; // error!

在这种情况下(恕我直言)你应该做的不是使用数组,而是使用 ArrayList.老实说,几乎没有理由在 ArrayList 上使用数组,而泛型只是其中一个例子.

What you should be doing in this case (imho) is not using arrays but using an ArrayList. In all honesty, there is very little reason to use arrays over an ArrayList and generics is just one example of that.

要获得更好更完整的解释,请参阅(优秀)Java 泛型常见问题解答:

For a better and more complete explanation see the (excellent) Java Generics FAQ:

不,因为它不是类型安全的.

数组是协变的,这意味着超类型引用的数组是子类型数组的超类型参考.也就是说,Object[] 是一个String[] 的超类型和一个字符串数组可以通过Object[] 类型的引用变量.

Arrays are covariant, which means that an array of supertype references is a supertype of an array of subtype references. That is, Object[] is a supertype of String[] and a string array can be accessed through a reference variable of type Object[].

...

这篇关于Java 中的通用数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆