Java 在方法中返回泛型类型T
下面的类模拟可以用Ts填充的泛型矩阵,其中Java 在方法中返回泛型类型T,java,generics,types,casting,Java,Generics,Types,Casting,下面的类模拟可以用Ts填充的泛型矩阵,其中 public class GenMatrix<T extends Number> { //local matrix T[][] matrix; public GenMatrix(T[][] matrix) { //if matrix is n x n, set it as local if (matrix.length == matrix[0].length) this.matrix = matrix;
public class GenMatrix<T extends Number> {
//local matrix
T[][] matrix;
public GenMatrix(T[][] matrix) {
//if matrix is n x n, set it as local
if (matrix.length == matrix[0].length)
this.matrix = matrix;
}
//multiplies the matrix with a vector of the same type T and returns a Double vector
Double[] multVector (T[] vector){
//check wether the matrix can be multiplied with the vector
if (vector.length != matrix.length) return null;
//new Double vector
Double[] result = new Double[matrix.length];
//matrix - vector -multiplication
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
//cast all Ts into Doubles
result[j] += ((Double)matrix[i][j])*((Double)vector[j]);
}
}
return result;
}
}
正如您所看到的,multVector方法。。返回一个双精度[]。
我的问题:为什么它不能返回一个t[]?如果我不将计算中的矩阵和向量项转换为双精度,编译器会说T类型的运算符*未知。我想知道,因为T扩展了数字,数字是可计算的,不是吗?。
我不是在寻找一个返回T[]向量的变通方法,而是为了回答为什么它不起作用的问题
关于Tak3r07当某物扩展数字时,您不必将其强制转换为Double、Integer或任何其他子类。了解Java中基本数据类型和对象数据类型之间的区别。数值运算符仅对基元类型起作用。如果将强制转换应用于Double并使用*,Java将执行一个称为自动取消装箱的过程
您的强制转换可能会遇到ClassCastException。而不是这个
result[j] += ((Double)matrix[i][j])*((Double)vector[j]);
这样做:
result[j] += (matrix[i][j].doubleValue())*(vector[j].doubleValue());
没有为数字定义数学运算符。它们是为数字原语定义的:byte、short、int、long。你可以说的原因是:
Integer i = 5;
int j = i + 2;
是自动装箱,在表达式i+2中自动将i替换为i.intValue
这就是不能将+运算符与泛型类型T一起使用的原因
方法multVector可以返回泛型类型:T[]multVector[]输入。为此,应将*`的定义传递给方法:
interface MathOperator<T> {
perform(T one, T two);
}
class MultiplyDouble implements MathOperator<Double> {
perform(Double one, Double two) {
return one * two;
}
}
T[] multVector (T[] vector, MathOperator<T> operator){...}
顺便说一句,创建泛型数组的实例也是一项挑战。提示:用户类java.lang.reflect.Array。multVector当然可以返回一个T数组。问题是:
不能对类型变量或数字类执行操作
不能创建变量类型的数组
对于第一部分,您必须知道由T表示的实际类。因此您应该有:
...
T[][] matrix;
Class<T> clazz;
public GenMatrix(T[][] matrix, Class<T> clazz) {
//if matrix is n x n, set it as local
if (matrix.length == matrix[0].length)
this.matrix = matrix;
this.clazz = clazz;
}
...
T[] result = (T[]) Array.newInstance(clazz, matrix.length);
...
对于第二种情况,您可以继续进行双精度计算,并在最后进行铸造:
abstract <T> fromDouble(double value); // to be implemented in actual class
//matrix - vector -multiplication
double res;
for (int j = 0; i < matrix.length; i++) {
res = 0.;
for (int i = 0; j < matrix[0].length; j++) {
//cast all Ts into Doubles
res += matrix[i][j].doubleValue() * vector[j].doubleValue();
}
resul[j] = fromDouble(res);
}
正如您所看到的,对于有限的增益来说,它要复杂得多。*是某些基本数据类型的特殊运算符。如果您希望能够将类中包含的数字相乘,则必须使用类似于乘法的方法将T限制为类。
abstract <T> fromDouble(double value); // to be implemented in actual class
//matrix - vector -multiplication
double res;
for (int j = 0; i < matrix.length; i++) {
res = 0.;
for (int i = 0; j < matrix[0].length; j++) {
//cast all Ts into Doubles
res += matrix[i][j].doubleValue() * vector[j].doubleValue();
}
resul[j] = fromDouble(res);
}