Java:原始数据类型的数组不是autobox

时间:2009-02-05 20:24:20

标签: java generics autoboxing

我有这样的方法:

public static <T> boolean isMemberOf(T item, T[] set)
{
    for (T t : set) {
        if (t.equals(item)) {
            return true;
        }
    }
    return false;
}

现在,我尝试使用char T来调用此方法:

char ch = 'a';
char[] chars = new char[] { 'a', 'b', 'c' };
boolean member = isMemberOf(ch, chars);

这不起作用。我希望charchar[]能够自动生成CharacterCharacter[],但这似乎不会发生。

任何见解?

10 个答案:

答案 0 :(得分:37)

数组没有自动装箱,仅适用于基元。我相信这是你的问题。

答案 1 :(得分:13)

为什么将char[]装箱到Character[]?数组总是引用类型,因此不需要装箱。

此外,它将非常昂贵 - 它将涉及创建一个新数组,然后依次装箱每个char。糟糕!

答案 2 :(得分:3)

你可以使用反射来获得适用于所有类型数组的方法,但是你会失去类型安全性,所以这可能不是你想要的。

import java.lang.reflect.Array
public static boolean isMemberOfArray(Object item, Object array)
{
    int n = Array.getLength(array)
    for (int i = 0; i < n; i++) {
        if (Array.get(array, i).equals(item)) {
            return true;
        }
    }
    return false;
}

答案 3 :(得分:2)

正确,数组没有自动装箱(在int[] ints; ...; Arrays.asList(ints)的情况下导致奇怪 - asList返回一个包含单个Object的数组,即数组!)

这是一个用于装箱阵列的简单实用程序。

public static Integer[] boxedArray(int[] array) {
    Integer[] result = new Integer[array.length];
    for (int i = 0; i < array.length; i++)
        result[i] = array[i];
    return result;
}

当然,每种基本类型都需要不同的版本。

答案 4 :(得分:1)

这似乎是设计上的,既可以避免这种昂贵的自动装箱操作,又可以使泛型必须与现有的Java字节码向后兼容。

例如,请参阅this articlethis bug

答案 5 :(得分:1)

数组是一种低级实现类型的东西。 char[]将是一个具有双字节字符的连续内存区域。 Character[]将是一个连续的内存区域,具有四个或八个字节的引用。你不能得到Character[]来包装char []。但是List<Character>可以包裹char[]

除非您编写低级代码,否则引用数组通常不是一个好主意。如果您愿意,您可以编写或获得等效的java.util.Arrays.asList

答案 6 :(得分:1)

正如其他人所提到的,对于基元数组没有自动装箱。如果要将方法与原始数组一起使用,则需要为每种基本类型提供重载。这似乎是在类库中执行操作的标准方法。例如,请参阅java.util.Arrays中的重载。

答案 7 :(得分:1)

首先,我会尝试尽可能多地避免使用数组,而不是使用列表。

阵列没有自动装箱,但是varargs有自动装箱。因此,如果您将方法声明为(使用相同的主体):

public static <T> boolean isMemberOf(T item, T ... set)

然后你可以写

isMemberOf('a', 'a', 'b', 'c');

就个人而言,我更喜欢使用谷歌的番石榴,在那里你可以写一些像

这样的东西
char ch = 'a';
char[] chars = new char[] { 'a', 'b', 'c' };
boolean member = isMemberOf(ch, Chars.asList(chars).toArray(new Character[0]));

你的代码可能只是一个例子,但如果你真的想测试会员资格,你可以这样做:

Chars.contains(chars, ch);

or

ImmutableSet.of('a', 'b', 'c').contains('a')

答案 8 :(得分:1)

输入Java 8并让primArray成为PrimType[]类型的标识符,然后您可以执行以下操作:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);

答案 9 :(得分:0)

更简单的方法是

char ch = 'a';
String chars = "abc";
boolean member = chars.indexOf(ch) >= 0;