Java:原始数据类型数组不会自动装箱
我有一个这样的方法:
public static <T> boolean isMemberOf(T item, T[] set)
{
for (T t : set) {
if (t.equals(item)) {
return true;
}
}
return false;
}
现在我尝试使用 T
的 char
来调用此方法:
char ch = 'a';
char[] chars = new char[] { 'a', 'b', 'c' };
boolean member = isMemberOf(ch, chars);
这不起作用。 我希望 char
和 char[]
自动装箱为 Character
和 Character[]
,但这并没有似乎没有发生。
有什么见解吗?
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 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.
Any insights?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
数组没有自动装箱功能,仅适用于基元。 我相信这是你的问题。
There is no autoboxing for arrays, only for primitives. I believe this is your problem.
为什么
char[]
会被装箱到Character[]
? 数组始终是引用类型,因此不需要装箱。此外,它会非常昂贵 - 它将涉及创建一个新数组,然后依次装箱每个字符。 哎呀!
Why would
char[]
be boxed toCharacter[]
? Arrays are always reference types, so no boxing is required.Furthermore, it would be hideously expensive - it would involve creating a new array and then boxing each char in turn. Yikes!
您可以使用反射来获取适用于所有类型数组的方法,但您会失去类型安全性,因此这可能不是您想要的。
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.
正确,数组没有自动装箱(这会导致像
int[] ints; ...; Arrays.asList(ints)
这样的情况出现奇怪的情况 - asList 返回一个包含单个对象的列表,即数组!)这是一个用于装箱数组的简单实用程序。
当然,每种基本类型都需要不同的版本。
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!)Here's a simple utility to box an array.
You will need a different version for each primitive type, of course.
这似乎是设计使然,既是为了避免如此昂贵的自动装箱操作,也是因为泛型必须与现有的 Java 字节码向后兼容。
请参阅本文和此错误。
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.
See this article and this bug, for example.
数组是一种低级实现类型。
char[]
将是一个包含两字节字符的连续内存区域。Character[]
将是具有四个或八字节引用的连续内存区域。 您无法使用Character[]
来包装 char[]。 然而,List
可以包装char[]
。引用数组通常不是一个好主意,除非您正在编写低级代码。 如果您愿意,您可以编写或获取
java.util.Arrays.asList
的等效项。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 aCharacter[]
to wrap a char[]. However aList<Character>
could wrap achar[]
.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,例如。
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.
首先,我会尽量避免使用数组,而是使用列表。
数组没有自动装箱,但可变参数有自动装箱。 因此,如果您将您的方法声明为(具有相同的主体):
那么您可以编写
个人,我更喜欢使用谷歌的番石榴,您可以在其中编写类似的内容
您的代码可能只是一个示例,但如果您真的想测试成员资格,请在你可以这样做:
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):
then you can write
Personally, I prefer using google's guava, where you can write things like
Your code was probably just an example, but if you really wanted to test membership, in you can do it like this:
输入 Java 8 并让
primArray
为PrimType[]
类型的标识符,然后您可以执行以下操作:<代码>
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);
Enter Java 8 and let
primArray
be an identifier of typePrimType[]
, then you can do the following:BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);
一个更简单的方法是
A simpler way to do this is