返回方法中的泛型类型T.

时间:2014-06-10 11:37:22

标签: 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;
}

//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(..)返回Double []。 我的问题:为什么它不能返回T []?如果我不将计算中的矩阵和向量条目转换为Double,编译器会说“操作符”*“对于类型T是未知的”。我想知道,因为T扩展数字和数字是一个可计算的(不是吗?)。 我不是在寻找一个解决方法来返回一个T []向量,而是为了回答“为什么它不起作用”-question。

关心Tak3r07

3 个答案:

答案 0 :(得分:0)

当某些内容延伸Number时,您无法将其转换为DoubleInteger或任何其他子类。阅读Java中原语和Object数据类型之间的区别。数字运算符仅适用于基元类型。将演员表应用到Double并使用*时会发生什么情况,Java会执行一个名为自动取消装箱的过程。

你的演员阵容可能会遇到ClasscastException。而不是这个

result[j] += ((Double)matrix[i][j])*((Double)vector[j]);

这样做:

result[j] += (matrix[i][j].doubleValue())*(vector[j].doubleValue());

答案 1 :(得分:0)

未为Number定义数学运算符。它们是为数字基元定义的:byteshortintlong。您可以说:

Integer i = 5;
int j = i +  2;

autoboxing 会自动将i替换为i.intValue()i + 2中的表达式+

这就是您不能将T运算符与泛型multVector()一起使用的原因。

方法. To do this you should pass your definition of可以返回泛型类型:T [] multVector(T [] input)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){...} *`到方法:

multVector (new Double[] {1.1, 2.2, 3.3}, new MultiplyDouble());

现在您可以按以下方式调用此方法:

java.lang.reflect.Array

BTW创建通用阵列的实例也是挑战。提示:用户类{{1}}。

答案 2 :(得分:0)

multVector当然可以返回一个T数组。问题是:

  • 您不能对类型变量进行操作,也不能对Number
  • 进行操作
  • 您无法创建类型变量数组

对于第一部分,你必须知道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);
...

对于第二种情况,你可以继续对double进行计算并在最后进行投射:

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

如你所见,有限的收益要复杂得多。