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

时间:2020-11-25 16:27:02

I have a method like this:

我有这样的方法:

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

Now I try to call this method using a char for T:

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

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

This doesn't work. I would expect the char and char[] to get autoboxed to Character and Character[], but that doesn't seem to happen.

这不起作用。我希望char和char []能够自动装入Character和Character [],但这似乎不会发生。

Any insights?

10 个解决方案

#1


34  

There is no autoboxing for arrays, only for primitives. I believe this is your problem.

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

#2


12  

Why would char[] be boxed to Character[]? Arrays are always reference types, so no boxing is required.

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

Furthermore, it would be hideously expensive - it would involve creating a new array and then boxing each char in turn. Yikes!

此外,它将非常昂贵 - 它将涉及创建一个新的数组,然后轮流装箱每个char。哎呀!

#3


3  

You could use reflection to get a method that works for all types of arrays, but you would lose type safety, so this is probably not what you want.

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

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;
}

#4


2  

Correct, there is no autoboxing for arrays (which results in weirdness in cases like int[] ints; ...; Arrays.asList(ints) - asList returns a List containing a single Object, the array!)

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

Here's a simple utility to box an array.

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

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;
}

You will need a different version for each primitive type, of course.

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

#5


1  

This appears to be by design, both to avoid such an expensive autoboxing operation, and because generics have to be backwards-compatible with the existing Java bytecode.

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

See this article and this bug, for example.

例如,请参阅此文章和此错误。

#6


1  

Arrays are a low-level implementation type of thing. char[] will be a contiguous area of memory with two-byte chars. Character[] will be a contiguous area of memory with four or eight-byte references. You cannot get a Character[] to wrap a char[]. However a List<Character> could wrap a char[].

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

Arrays of references are not usually a good idea unless you are writing low-level code. You could, if you wish, write or obtain an equivalent of java.util.Arrays.asList.

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

#7


1  

As others have mentioned, there is no autoboxing for arrays of primitives. If you want to use your method with primitive arrays, you will need to provide an overload for each primitive type. This seems to be the standard way of doing things in the class libraries. See the overloads in java.util.Arrays, for example.

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

#8


1  

First, I would try to avoid arrays as much as you can, use lists instead.

首先,我会尽量避免使用数组,而是使用列表。

There is no autoboxing for arrays, but there is autoboxing for varargs. So if you declare your method as (with the same body):

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

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

then you can write

然后你就可以写了

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

Personally, I prefer using google's guava, where you can write things like

就个人而言,我更喜欢使用谷歌的番石榴,在那里你可以写出类似的东西

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

Your code was probably just an example, but if you really wanted to test membership, in you can do it like this:

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

Chars.contains(chars, ch);

or

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

#9


1  

Enter Java 8 and let primArray be an identifier of type PrimType[], then you can do the following:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);

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

#10


0  

A simpler way to do this is

一种更简单的方法是

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

#1


34  

There is no autoboxing for arrays, only for primitives. I believe this is your problem.

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

#2


12  

Why would char[] be boxed to Character[]? Arrays are always reference types, so no boxing is required.

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

Furthermore, it would be hideously expensive - it would involve creating a new array and then boxing each char in turn. Yikes!

此外,它将非常昂贵 - 它将涉及创建一个新的数组,然后轮流装箱每个char。哎呀!

#3


3  

You could use reflection to get a method that works for all types of arrays, but you would lose type safety, so this is probably not what you want.

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

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;
}

#4


2  

Correct, there is no autoboxing for arrays (which results in weirdness in cases like int[] ints; ...; Arrays.asList(ints) - asList returns a List containing a single Object, the array!)

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

Here's a simple utility to box an array.

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

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;
}

You will need a different version for each primitive type, of course.

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

#5


1  

This appears to be by design, both to avoid such an expensive autoboxing operation, and because generics have to be backwards-compatible with the existing Java bytecode.

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

See this article and this bug, for example.

例如,请参阅此文章和此错误。

#6


1  

Arrays are a low-level implementation type of thing. char[] will be a contiguous area of memory with two-byte chars. Character[] will be a contiguous area of memory with four or eight-byte references. You cannot get a Character[] to wrap a char[]. However a List<Character> could wrap a char[].

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

Arrays of references are not usually a good idea unless you are writing low-level code. You could, if you wish, write or obtain an equivalent of java.util.Arrays.asList.

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

#7


1  

As others have mentioned, there is no autoboxing for arrays of primitives. If you want to use your method with primitive arrays, you will need to provide an overload for each primitive type. This seems to be the standard way of doing things in the class libraries. See the overloads in java.util.Arrays, for example.

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

#8


1  

First, I would try to avoid arrays as much as you can, use lists instead.

首先,我会尽量避免使用数组,而是使用列表。

There is no autoboxing for arrays, but there is autoboxing for varargs. So if you declare your method as (with the same body):

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

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

then you can write

然后你就可以写了

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

Personally, I prefer using google's guava, where you can write things like

就个人而言,我更喜欢使用谷歌的番石榴,在那里你可以写出类似的东西

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

Your code was probably just an example, but if you really wanted to test membership, in you can do it like this:

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

Chars.contains(chars, ch);

or

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

#9


1  

Enter Java 8 and let primArray be an identifier of type PrimType[], then you can do the following:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);

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

#10


0  

A simpler way to do this is

一种更简单的方法是

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