Java 在方法中返回泛型类型T

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;

下面的类模拟可以用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;
}

//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);
    }