Java Class java.lang.reflect.Array提供了一组用于动态创建数组的工具。然而,除此之外,它还有一整套用于访问(获取,设置和长度)数组的方法。我不明白这一点,因为您可以(并且可能会)在创建时将动态生成的数组转换为数组,这意味着您可以使用常规数组访问(括号表示法)功能。实际上,查看源代码,您可以看到这是所有类所做的,转换数组,并在转换失败时抛出异常。
那么所有这些额外方法的重点/用处是什么?
更新
所有原始get*()
和set*()
方法似乎尤其无用,考虑到您需要预先知道数组的类型以便知道使用哪种方法。
更新2
谢谢大家,您的意见非常有教育意义!我无法真正看到我何时将此类用于newInstance()
以外的任何事情(也许getLength()
),但我现在意识到这些其他方法仍然相当是有用的。
答案 0 :(得分:8)
这个类非常深奥 - 大多数数组的使用都知道数组的类型,所以在实现一般处理数组的代码时,这个类通常最有用。
所有数组都没有数组超类,因此无论类型如何,都没有统一的方法来访问元素或数组的大小。 java.lang.reflect.Array
填补了这个空白,允许您以相同的方式访问数组,无论类型如何。例如,从任何数组获取给定索引处的值(作为对象返回)。
这是parameteric polymorphism。当然,你可以自己编码,如果你知道类型 - 你只是演员。如果您不知道数组类型,或者它可以是几种类型,您可以检查可能性并进行适当的转换 - 这是reflect.Array
中的代码所做的。
编辑:回应评论。考虑如何解决此问题 - 如何计算值在数组中重复的次数。如果没有类型无关的Array类,如果没有显式地转换数组,就不可能进行编码,因此每个数组类型都需要不同的函数。在这里,我们有一个函数可以处理任何类型的数组。
public Map<Object, Integer> countDuplicates(Object anArray)
{
if (!anArray.getClass().isArray())
throw new IllegalArgumentException("anArray is not an array");
Map<Object,Integer> dedup = new HashMap<Object,Integer>();
int length = Array.getLength(anArray);
for (int i=0; i<length; i++)
{
Object value = Array.get(anArray, i);
Integer count = dedup.get(value);
dedup.put(value, count==null ? 1 : count+1);
}
return dedup;
}
EDIT2:关于get *()和set *()方法。上面的源代码链接链接到Apache和声。那里的实现不遵守Sun Javadocs。例如,来自getInt方法
@throws IllegalArgumentException If the specified object is not an array,
or if the indexed element cannot be converted to the return type
by an identity or widening conversion
这意味着实际数组可以是byte[]
,short[]
或int[]
。 Harmony实现不是这种情况,只需要int[]
。 (顺便提一下,Sun实现对大多数Array类使用本机方法。)get *()和set *()方法的出现与get()
,getLength()
相同 - 提供(松散地)类型不可知的数组访问。
并不是每天都需要使用的东西,但我认为它为那些需要它的人提供了价值。
答案 1 :(得分:2)
如果您知道“该对象是某种(可能是原始的)类型的数组”,这些方法可以减轻您自己检查和转换数组的负担。
我自己只在框架和实用程序中看到过这种情况,例如commons-beanutils
。该框架反射访问java bean的属性,并使用Array
方法访问数组属性的元素。
答案 2 :(得分:2)
关于set...()
方法,它们提供了一些用途:
Object a = new byte[1], b = new short[1], c = new int[1], d = new long[1];
Array.setByte(a, 0, (byte)1);
Array.setByte(b, 0, (byte)1);
Array.setByte(c, 0, (byte)1);
Array.setByte(d, 0, (byte)1);
例如,您无需知道要处理的数组是int[]
还是long[]
来将值设置为5
。
编辑我更改了示例以希望证明set...()
方法允许您不必静态地知道原始数组的类型。