簡體   English   中英

泛型類的類型安全錯誤

[英]Type safety error with generic class

編輯:設置

有一個解析器,它從ProgramFactory調用方法,該工廠使用表達式,語句,類型和程序,如下面實現的標頭所示。 ProgramFactory實現IProgramFactory,它是一個類似於此public interface IProgramFactory<E, S, T, P>

我似乎遇到的問題是Expression也是通用的,我不知道如何在實現中(在標頭和方法中)正確實現

當只有返回類型為Expression類型時,它似乎起作用,如此處所示

    @Override
public Expression<Boolean> createTrue(SourceLocation sourceLocation) {
    True expr = new True();
    return expr;
}

但是當變量的類型也為Expression時不是

我這樣做是為了使返回類型和參數類型的通配符不必相同

public abstract class BinaryExpression<T, R> extends Expression<T>{
    Expression<R> left;
    Expression<R> right;
}

在接口的實現中,我似乎一遍又一遍地遇到相同的問題。

 Expression is a raw type. References to generic type Expression<T> should be parameterized 

問題是當我對這些表達式進行參數化時,它們告訴我接​​口沒有此方法。

 The method createAddition(Expression<Double>, Expression<Double>, SourceLocation) of type ProgramFactory must override or implement a supertype method 

這是實現的樣子

@Override
public Expression<Double> createAddition(Expression left, Expression right, SourceLocation sourceLocation) {
    Addition expr = new Addition(left, right);
    return expr;
}

這就是界面的樣子

/** An expression that evaluates to the sum of the given expressions */
E createAddition(E left, E right, SourceLocation sourceLocation);

這是Addition類的樣子

public class Addition extends BinaryExpression<Double, Double>{ 
    public Addition(Expression<Double> left, Expression<Double> right){
        this.left = left;
        this.right= right;
    }

     @Override
     public Double eval() {
         Double sum = left.eval() + right.eval();
         return sum;
     }
}

這是Expression類的樣子

public abstract class Expression<T> {
    public abstract T eval();
}

這是實現標頭的樣子

public class ProgramFactory implements IProgramFactory<Expression<?>, Statement, Type, Program>{

您沒有提供完整的界面實現。 所以我可以認為是這樣的:

class MyImplementation implements Interface<Expression> {
        @Override
        public Expression<Double> createAddition(Expression left, Expression right, SourceLocation sourceLocation) {
            Addition expr = new Addition(left, right);
            return expr;
        }
}

但是應該像這樣:

class MyImplementation implements Interface<Expression<Double>> {
        @Override
        public Expression<Double> createAddition(Expression<Double> left, Expression<Double> right, SourceLocation sourceLocation) {
             Addition expr = new Addition(left, right);
             return expr;
        }
}

這是原始類型Expression = |Expression<E>| 並在方法參數中使用簡單的Expression ,可以擦除類型參數。 您不能使用類型為parameter(CTE)的參數在接口實現中聲明原始Expression和override方法。 考慮類型參數,就像它們是簡單別名一樣。

您的表達式類應如下所示,

class Expression<T> {
  ....
}

您的界面應如下所示,

@Override
public Expression<?> createAddition(Expression<?> left, Expression<?> right, SourceLocation sourceLocation) {
     Addition expr = new Addition(left, right);
     return expr;
}

並且也使您的Expression類成為通用類。 創建你的

它將解決您的問題。

如果您在接口中顯式參數化所有參數:

public interface IProgramFactory<T> {
  public Expression<T> createAddition(
      Expression<T> left,
      Expression<T> right,
      SourceLocation sourceLocation
  );
}

然后,您可以執行以下操作:

public class ProgramFactory implements IProgramFactory<Double>{
  @Override
  public Expression<Double> createAddition(
      Expression<Double> left,
      Expression<Double> right,
      SourceLocation sourceLocation
  ){
    Expression<Double> expr = new Addition( left, right );
    return expr;
  }
}

暫無
暫無

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

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