我的Java代码存在问题。我想通过使用泛型类型来使我的方法具有通用性。用代码解释它更容易:
public interface Destroyable {
void destroy();
default void destroyArray(byte[] array) {
Arrays.fill(array, (byte)0);
}
default void destroyArray(char[] array) {
Arrays.fill(array, (char)0);
}
}
关键是,我希望我的默认方法destroyArray可以使用任何类型,如下所示:
public interface Destroyable {
void destroy();
default <E> void destroyArray(Class<E>[] array) {
Arrays.fill(array, (E)0);
}
}
它给了我错误:
不可转换的类型;无法投射&#39; int&#39;到&#39; E&#39;
有没有简单的解决方案来实现这个目标?
答案 0 :(得分:9)
您的代码存在问题:
default <E> void destroyArray(E[] array) {
Arrays.fill(array, (E) 0);
}
一般E
类型当然不一定是int
(或者像Integer
那样可以自动装箱的东西)。但是你想要实际写一些默认值。因此,您需要创建E
的有效实例。总的来说,这很难,因为你对类型一无所知,包括它的构造函数。
但是,所有Object
都有一个有效值,即null
。它表明目前根本就没有实例。
因此以下内容适用于任意类型E
:
default <E> void destroyArray(E[] array) {
Arrays.fill(array, null);
}
但是,由于int[]
E
只能用于Object
,而不是基元,因此您仍然无法填充default void destroyArray(int[] array) {
Arrays.fill(array, 0);
}
default void destroyArray(double[] array) {
Arrays.fill(array, 0.0);
}
// ...
等基本类型数组。您需要为每个原语硬编码其他方法:
Class<E>
Class<E>[]
您的原始代码有E[]
而不是Class<E>
。请注意,E[]
表示与Class<E>
完全不同的内容。
Class
是一个E
对象,它是一个包装器,提供对分析类的内容的Reflection-API访问权限。就像获取方法的名称和类似的东西。而Person
是类本身。
所以Person
将是Class<Person>
类,而Person
就像一个类,它知道Class
类的内容,就像它的方法名一样。
有关详细信息,请参阅~/.bundle/config
的{{3}}。
答案 1 :(得分:4)
default <E> void destroyArray(E[] array) {
Arrays.fill(array, null);
}
以上可能就是您的意图。 然而,这不适用于原始类型。由于原始类型不允许作为泛型类型参数传递,因此您仍需要destroyByteArray
,destroyIntArray
等。
此外,destroyArray
似乎不属于Destroyable
。难道它只是在一个充满静态方法的辅助类中吗?如果我是你,我会把它移到那里。它甚至没有调用destroy
方法,因此没有理由进入Destroyable
。
答案 2 :(得分:3)
使用许多重载方法的原始方法很好。
对于基本类型,泛型适用于数组:
default <A> void destroyArray(A array) {
Class<?> arrayType = array.getClass();
if (!arrayType.isArray()) {
return;
}
Class<?> type = arrayType.getComponentType();
if (type == int.class) {
Arrays.fill((int[])array, 0);
} else if (type == char.class) {
Arrays.fill((char[])array, '\0');
}
//...
}
正如您所看到的:这几乎不是更紧凑,更慢,更少类型安全,并且安全被遗忘的原始类型。