Java:原始数据类型数组不会自动装箱
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/517751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: Array of primitive data types does not autobox
提问by David Koelle
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
for调用此方法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
andchar[]
自动装箱到Character
and Character[]
,但这似乎没有发生。
Any insights?
任何见解?
采纳答案by Eddie
There is no autoboxing for arrays, only for primitives. I believe this is your problem.
数组没有自动装箱,只有基元。我相信这是你的问题。
回答by Jon Skeet
Why would char[]
be boxed to Character[]
? Arrays are alwaysreference 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!
此外,它会非常昂贵 - 它会涉及创建一个新数组,然后依次装箱每个字符。哎呀!
回答by Josh Lee
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 articleand this bug, for example.
回答by Tom Hawtin - tackline
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[]
将是具有四或八字节引用的连续内存区域。你不能用 aCharacter[]
来包装一个 char[]。但是 aList<Character>
可以包装 a 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
.
回答by Peter Lawrey
A simpler way to do this is
一个更简单的方法是
char ch = 'a';
String chars = "abc";
boolean member = chars.indexOf(ch) >= 0;
回答by Peter Lawrey
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[] ints; ...; Arrays.asList(ints)
- asList 返回一个包含单个对象的列表,数组!)
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.
当然,每种原始类型都需要不同的版本。
回答by newacct
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;
}
回答by Ben Lings
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 中的重载。
回答by Jirka
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):
数组没有自动装箱,但可变参数有自动装箱。因此,如果您将方法声明为(具有相同的主体):
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')
回答by bodmas
Enter Java 8 and let primArray
be an identifier of type PrimType[]
, then you cando the following:BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);
输入 Java 8 并primArray
设为 type 的标识符PrimType[]
,然后您可以执行以下操作:BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);