问题描述
有没有办法获得与类相关的二元运算符? 我有这个方法有两个参数:
public <T extends Number> T[] sumArray(T[] arrayToAdd,BinaryOperator<T> add){
T[] arrayToReturn = arrayToAdd.clone();
for (int i = 0; i < arrayToAdd.length; i++) {
arrayToReturn[i] = arrayToAdd[i];
for (int j = 0; j < i; j++) {
arrayToReturn[i] = add.apply(arrayToReturn[i],arrayToAdd[j]);
}
}
return arrayToReturn;
}
但是,我想做这样的事情:
public <T extends Number> T[] sumArray(T[] arrayToAdd){
BinaryOperator add = arrayToAdd.getClass().getBinaryOperator(sum);
T[] arrayToReturn = arrayToAdd.clone();
for (int i = 0; i < arrayToAdd.length; i++) {
arrayToReturn[i] = arrayToAdd[i];
for (int j = 0; j < i; j++) {
arrayToReturn[i] = add.apply(arrayToReturn[i],arrayToAdd[j]);
}
}
return arrayToReturn;
}
PD:从另一个类调用第一种方法时,我也遇到了问题:
api.sumArray(intArray,Integer::sum);
错误说:'对象不能转换为 int'
-------------------编辑-------------------
最小可重现示例
public class guide6Main<T extends Comparable<T>,N extends Number> {
public static void main(String[] args) {
ApiArray api = new ApiArray();
Integer[] intArray = {1,2,3,4};
api.exercise6(intArray,Integer::sum);
}
}
public class ApiArray<T extends Comparable<T>,N extends Number> {
public <N extends Number> N[] exercise6(N[] arrayToAdd,BinaryOperator<N> add){
N[] arrayToReturn = arrayToAdd.clone();
for (int i = 0; i < arrayToAdd.length; i++) {
arrayToReturn[i] = arrayToAdd[i];
for (int j = 0; j < i; j++) {
arrayToReturn[i] =add.apply(arrayToReturn[i],arrayToAdd[j] );
}
}
return arrayToReturn;
}
}
这是错误:
D:\Documentos\Austral\Álgerba III\src\Guia6\Team2Solution\guide6Main.java:11:49
java: incompatible types: invalid method reference
incompatible types: java.lang.Object cannot be converted to int
P.D.2:另外,arrayToAdd
不能包含类型的混合,我的意思是,它可以,但在这种情况下不是
(最小的可重现示例好吗?我从来没有做过这样的事情)
解决方法
纯粹回答错误“incompatible types: java.lang.Object cannot be converted to int
”:
public class guide6Main<T extends Comparable<T>,N extends Number> {
public static void main(String[] args) {
ApiArray api = new ApiArray();
Integer[] intArray = {1,2,3,4};
api.exercise6(intArray,Integer::sum);
}
}
public class ApiArray<T extends Comparable<T>,N extends Number> {
public <N extends Number> N[] exercise6(N[] arrayToAdd,BinaryOperator<N> add){
// ...
}
}
ApiArray
是泛型类型,但 ApiArray api
是原始类型变量(它没有类型参数)。
原始类型删除所有泛型,即使是那些与省略的类型参数无关的泛型。
使用通配符类型声明 api
:
ApiArray<?,?> api = new ApiArray<>();
(或者,显然,在那里放入非通配符类型,如果有您可以有效添加的类型)。
如果不需要,请从类中删除类型参数。
,您的课程设计在这一点上不是最佳的。
您的方法隐藏了 N
的类参数。
所以当你这样做
ApiArray api = new ApiArray();
Integer[] intArray = {1,4};
api.exercise6(intArray,Integer::sum);
您正在使用原始类型(请参阅 ApiArray api 而不提供类型),这将导致 N
只是 object
,因为 N
未绑定在这一点上的任何类型。这将导致 N
被擦除为 Object
,因为 Object
是最不高级的类型。
因此,在实例化 T
类时,您需要为 N
和 ApiArray
提供泛型类型 - 例如:
ApiArray<Integer,Integer> api = new ApiArray();
Integer[] intArray = {1,4};
api.exercise6(intArray,Integer::sum );
实现结果的另一种方法是删除类的泛型类型边界:
class ApiArray {
public <N extends Number> N[] exercise6(N[] arrayToAdd,BinaryOperator<N> add){
N[] arrayToReturn = arrayToAdd.clone();
for (int i = 0; i < arrayToAdd.length; i++) {
arrayToReturn[i] = arrayToAdd[i];
for (int j = 0; j < i; j++) {
arrayToReturn[i] =add.apply(arrayToReturn[i],arrayToAdd[j] );
}
}
return arrayToReturn;
}
}
这里的泛型类型/边界由方法签名提供。
另一种方法是从您的方法中删除泛型类型参数并使用类本身的泛型类型参数边界:
class ApiArray<T extends Comparable<T>,N extends Number> {
public N[] exercise6(N[] arrayToAdd,BinaryOperator<N> add){
N[] arrayToReturn = arrayToAdd.clone();
for (int i = 0; i < arrayToAdd.length; i++) {
arrayToReturn[i] = arrayToAdd[i];
for (int j = 0; j < i; j++) {
arrayToReturn[i] =add.apply(arrayToReturn[i],arrayToAdd[j] );
}
}
return arrayToReturn;
}
}
ApiArray<Integer,Integer> api = new ApiArray();
Integer[] intArray = {1,Integer::sum );