簡體   English   中英

Java泛型和加法運算的問題

[英]Problems with Java Generics and Addition arithmetic

有人知道我為什么會收到此錯誤嗎?

錯誤:找不到符號返回left.evaluate()+ right.evaluate(); 符號:方法validate()位置:類型T的左側變量,其中T是類型變量:T擴展在Operation類中聲明的對象

package expevaluator;

interface Expression<T> {

    T evaluate();
}

class Constant<T> implements Expression {

    private final T value;

    public Constant(T value) {
        this.value = value;
    }

    @Override
    public T evaluate() {
        return value;
    }

}

abstract class Operation<T> implements Expression {

    public T left;
    public T right;
}

class Addition<T> extends Operation {

    public Addition(T left, T right) {
        super.left = left;
        super.right = right;
    }

    @Override
    public T evaluate() {
        if(left instanceof Integer){
            if(right instanceof Integer){
                return super.left.evaluate() + right.evaluate();
            }else{
                return left.evaluate() + right.evaluate(); 
            }
        }else{
            return left.evaluate() + right.evaluate();
        }
    }
}

編輯:

package expevaluator;

import java.util.logging.Level;
import java.util.logging.Logger;

interface Expression<T extends Number> {

    T evaluate();
}

class Constant<T extends Number> implements Expression{

    private final T value;

    public Constant(T value) {
        this.value = value;
    }

    @Override
    public T evaluate() {
        return this.value;
    }

}

abstract class Operation<T> implements Expression {
    public T left;
    public T right;
}

class Addition extends Operation {

    public Addition(Constant left, Constant right) {
        super.left =  left.evaluate();
        super.right = right.evaluate();
    }

    @Override
    public Number evaluate() {
        String name = "expevaluator." + super.left.getClass().getSimpleName() + super.right.getClass().getSimpleName() + "Addition";
        try {
            Object instance;
            instance = Class.forName(name).newInstance();
            return (Number) instance;
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
            Logger.getLogger(Addition.class.getName()).log(Level.SEVERE, null, ex);
        }
        /*if (super.left instanceof Integer && super.right instanceof Integer) return new IntIntAddition().evaluate((Integer)super.left,(Integer)super.right);
        if (super.left instanceof Integer && super.right instanceof Double) return new IntDoubleAddition().evaluate((Integer)super.left,(Double)super.right);
        if (super.left instanceof Double && super.right instanceof Integer) return new DoubleIntAddition().evaluate((Double)super.left,(Integer)super.right);
        if (super.left instanceof Double && super.right instanceof Double) return new DoubleDoubleAddition().evaluate((Double)super.left,(Double)super.right);*/
        return null;

    }

}

class IntegerIntegerAddition{

    IntegerIntegerAddition() {

    }

    public Number evaluate(int left, int right) {
        return left + right;
    }

}

class IntegerDoubleAddition {

    public IntegerDoubleAddition() {
    }

    public Number evaluate(int left, double right) {
        return left + right;
    }
}
class DoubleIntegerAddition {

    public DoubleIntegerAddition() {
    }

    public Number evaluate(double left, int right) {
        return left + right;
    }
}
class DoubleDoubleAddition {

    public DoubleDoubleAddition() {
    }

    public Number evaluate(double left, double right) {
        return left + right;
    }
}

我一直很成功,現在我想在加法類中使用反射。

我想實例化一個類,然后調用validate()方法。

T永無界,所以它的上限是Object 因此,僅Object上的方法可用。

您正在混合表達式的值類型( T ,可以是Integer )和子表達式本身( Expression的子類型)。 也許應該看起來像這樣:

public Addition(Expression<T> left, Expression<T> right) {
   //...

還要注意, Constant<T>和類似的應該實現Expression<T> ,而不是原始類型Expression 同樣, Addition<T>應該擴展Operation<T> ,而不是Operation

就是說,您對Addition的使用方法總的來說是不可行的,因為它不能擴展到一般情況(您不能僅將+運算符應用於任何任意類型)。 我將僅針對Integer案例實施Addition

class IntegerAddition extends Operation<Integer> {

    private final Expression<Integer> left, right;

    public IntegerAddition(Expression<Integer> left, Expression<Integer> right) {
        this.left = left;
        this.right = right;
    }

    public Integer evaluate() {
        return left.evaluate() + right.evaluate();
    }
}

您需要在編譯時將super.leftExpression或任何其他包含super.left evaluate()函數的類型。 請記住,Java有類型擦除,是一個強類型語言,你Addition.Evaluate()方法是什么類型不知道leftright將在編譯時,由於評估()操作中沒有定義,有一個編譯器錯誤。

public T evaluate() {
    if(left instanceof Integer){
        if(right instanceof Integer){
            return ((Expression)super.left).evaluate() + ((Expression)right).evaluate();
        }else{
            return ((Expression)left).evaluate() + ((Expression)right).evaluate(); 
        }
    }else{
        return ((Expression)left).evaluate() + ((Expression)right).evaluate();
    }
}

此外,您不能添加由Java.Lang.Object evaluate()方法返回的對象,因為Java中的泛型實際上只是鍵入為Java.Lang.Object 相反,您將需要有一個類型感知的add()方法,該方法使用instanceOf運算符為您執行添加操作,因為無法在Java中覆蓋“ +”運算符。 (這似乎是您要實現的目標,您還沒有走滿100碼)

只需將泛型類型“變量”認為在Java中是沒有意義的,它們就可以幫助您避免在編譯時出現類型錯誤,但會以字節碼形式編譯為原始類型。

編輯:

另外...我不太確定block是什么:

if(left instanceof Integer){
        if(right instanceof Integer){

然后,您繼續調用left.evaluate()並嘗試將其添加到right.evaluate() ...但是這里的問題是您似乎沒有從Integer派生的任何東西,所以剩下的一切都奇怪了行為代碼。 如果你不知道你將處理整數,而所有的嵌套的leftright的對象也將是Integer S,你應該只投表達式為int,然后把它們相加。 更好的是,您應該使用Integer來限定類型,以便使用非通用類型限定的Addition類。

您至少有兩個問題。

  • leftright均為T類型,但是您嘗試在其上調用在類Constant<T>定義的evaluate() 由於leftright不一定是Constant<?>類型的,因此編譯器無法理解這些調用。
  • 您正在嘗試添加兩個類型為T表達式。 對於大多數T類型而言,這沒有意義。 例如,如果ab都是ColorInputStream類型,或者添加了其他沒有意義的東西,您期望a + b給您什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM