[英]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.left
為Expression
或任何其他包含super.left
evaluate()
函數的類型。 請記住,Java有類型擦除,是一個強類型語言,你Addition.Evaluate()
方法是什么類型不知道left
和right
將在編譯時,由於評估()操作中沒有定義,有一個編譯器錯誤。
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派生的任何東西,所以剩下的一切都奇怪了行為代碼。 如果你不知道你將處理整數,而所有的嵌套的left
和right
的對象也將是Integer
S,你應該只投表達式為int,然后把它們相加。 更好的是,您應該使用Integer來限定類型,以便使用非通用類型限定的Addition類。
您至少有兩個問題。
left
和right
均為T
類型,但是您嘗試在其上調用在類Constant<T>
定義的evaluate()
。 由於left
和right
不一定是Constant<?>
類型的,因此編譯器無法理解這些調用。 T
表達式。 對於大多數T
類型而言,這沒有意義。 例如,如果a
和b
都是Color
或InputStream
類型,或者添加了其他沒有意義的東西,您期望a + b
給您什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.