【问题标题】:Java Generics - Operator '*' cannot be applied to 'T', 'T' [duplicate]Java泛型-运算符'*'不能应用于'T','T'[重复]
【发布时间】:2021-10-09 10:11:54
【问题描述】:

我一直在学习 Java,最近了解了泛型类型,并想在我一直在研究的线性代数框架中使用它们。这是一些源代码。

package vector;

import java.util.Arrays;

abstract class AbstractVector <T> {

    T[] vector;

    public T get(int index) { return this.vector[index]; }

    public void set(int index, T value) { this.vector[index] = value; }

    public String toString() {
        return Arrays.toString(this.vector);
    }

    public double dotProduct(AbstractVector<T> vector) {
        double value = 0;

        for (int i=0; i<vector.size(); i++) {

            // This line causes issues
            value += this.vector[i] * vector.get(i);
        }

        return value;
    }

    public int size() {
        return this.vector.length;
    }

}

当我尝试对我的泛型类型使用任何数学运算时,我得到一个错误 Operator '*' cannot be applied to 'T', 'T'。如何解决这个问题?

【问题讨论】:

  • 通过不对泛型类型执行数学运算。它可以是 any 类型。就像Dog。在 Dog 类上执行乘法是什么意思? Java 支持用户类型的运算符重载。
  • @ElliottFrisch 回答得很好。要解决此问题,您可以将 T 限制为扩展 Numbers 所以public class AbstractVector &lt;T extends Number&gt;
  • @LuciferUchiha 对不起,这还不够。 Java 对原始数字类型(包括char)进行数学运算,而不是对Number 对象。

标签: java generics


【解决方案1】:

Lucifer Uchiha 在评论中走在了正确的轨道上:

要解决此问题,您可以将 T 限制为将 Numbers 扩展为公开 class AbstractVector &lt;T extends Number&gt;

您的第一步是告诉 Java 您的向量只能包含数字,不能包含任何引用类型。

abstract class AbstractVector <T extends Number> {

不过,我们仍然不在那里。虽然在算术表达式中使用时,Java 可以自动将Integer 拆箱到intDoubledouble,但它不知道将T 拆箱到哪个原始类型,甚至不知道TNumber 的一些子类。如果您知道您总是希望点积为double,则解决方案非常简单,因为Number 声明了doubleValue 方法(它在每个子类中单独实现,但我们不需要关心)。

        // This line no longer causes issues
        value += this.vector[i].doubleValue() * vector.get(i).doubleValue();

我们完成了。

您可以在这个相关问题中找到更多灵感:Generic type extending Number, calculations

【讨论】:

  • 感谢您的补充,我忘记了那部分:)
【解决方案2】:

为了在Java中进行数学运算,我们可以使用NUMBER类。 java.lang.Number 类是 BigDecimalBigIntegerByteDoubleFloatIntegerLongShort 类的超类。 Number 的子类必须提供方法将表示的数值转换为bytedoublefloatintlongshort

(资源:https://www.tutorialspoint.com/java/lang/java_lang_number.htm

public double dotProduct(AbstractVector<T> vector) {
    double value = 0;
    for (int i=0; i<vector.size(); i++) {
        //you can simply convert the return type to double
        value += this.vector[i].doubleValue() * vector.get(i).doubleValue();
        // if you need the output in different types then  intValue(),longValue(),floatValue() can be used.         
    }
    return value;
}

另一种使用泛型简单实现乘法的方法:

class Operations<T extends Number> {
    T mul(T t1, T t2) {
        if (t1 instanceof Double) {
            return (T) Double.valueOf((t1.doubleValue() * t2.doubleValue()));
        }
         else if (t1 instanceof Integer) {
            return (T) Integer.valueOf((t1.intValue() * t2.intValue()));
        }
        throw new IllegalArgumentException();
    }

    public static void main(String[] args) {
        Operations<Double> o1 = new Operations<Double>();
        System.out.print(o1.mul(2.0, 1.1));
        Operations<Integer> o2 = new Operations<Integer>();
        System.out.print(o2.mul(2, 11));   
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    相关资源
    最近更新 更多