Java 使用泛型类键入安全错误

Java 使用泛型类键入安全错误,java,generics,types,interface,abstract,Java,Generics,Types,Interface,Abstract,编辑:设置 有一个从ProgramFactory调用方法的解析器,该工厂使用表达式、语句、类型和程序,如下面实现的标题所示。 ProgramFactory实现IProgramFactory,这是一个类似以下内容的接口公共接口IProgramFactory 我似乎遇到的问题是,表达式也是泛型的,我不知道如何在实现中(在头和方法中)正确使用它 如图所示,当只有返回类型是Expression类型时,它似乎可以工作 @Override public Expression<Boolean&g

编辑:设置

有一个从ProgramFactory调用方法的解析器,该工厂使用表达式、语句、类型和程序,如下面实现的标题所示。 ProgramFactory实现IProgramFactory,这是一个类似以下内容的接口
公共接口IProgramFactory

我似乎遇到的问题是,表达式也是泛型的,我不知道如何在实现中(在头和方法中)正确使用它

如图所示,当只有返回类型是Expression类型时,它似乎可以工作

    @Override
public Expression<Boolean> createTrue(SourceLocation sourceLocation) {
    True expr = new True();
    return expr;
}
这就是类添加看起来的样子

/** An expression that evaluates to the sum of the given expressions */
E createAddition(E left, E right, SourceLocation sourceLocation);
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;
     }
}
public class ProgramFactory implements IProgramFactory<Expression<?>, Statement, Type, Program>{
公共类添加扩展了二进制表达式{
公共加法(表达式左、表达式右){
this.left=左;
这个。右=右;
}
@凌驾
公共双重评估(){
双和=left.eval()+right.eval();
回报金额;
}
}
这就是Expression类的外观

@Override
public Expression<Double> createAddition(Expression left, Expression right, SourceLocation sourceLocation) {
    Addition expr = new Addition(left, right);
    return expr;
}
public abstract class Expression<T> {
    public abstract T eval();
}
公共抽象类表达式{
公共摘要评估();
}
这就是实现的头的样子

/** An expression that evaluates to the sum of the given expressions */
E createAddition(E left, E right, SourceLocation sourceLocation);
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;
     }
}
public class ProgramFactory implements IProgramFactory<Expression<?>, Statement, Type, Program>{

公共类ProgramFactory实现IProgramFactory您的表达式类应该如下所示

class Expression<T> {
  ....
}
@Override
public Expression<?> createAddition(Expression<?> left, Expression<?> right, SourceLocation sourceLocation) {
     Addition expr = new Addition(left, right);
     return expr;
}
类表达式{
....
}
您的界面应该如下所示

class Expression<T> {
  ....
}
@Override
public Expression<?> createAddition(Expression<?> left, Expression<?> right, SourceLocation sourceLocation) {
     Addition expr = new Addition(left, right);
     return expr;
}
@覆盖
公共表达式createAddition(表达式左、表达式右、SourceLocation SourceLocation){
加法表达式=新加法(左、右);
返回表达式;
}
并使您的表达式类成为泛型类。创建您的


它将解决您的问题。

您没有提供完整的接口实现。所以我可以认为是这样的:

class MyImplementation implements Interface<Expression> {
        @Override
        public Expression<Double> createAddition(Expression left, Expression right, SourceLocation sourceLocation) {
            Addition expr = new Addition(left, right);
            return expr;
        }
}
类MyImplementation实现接口{
@凌驾
公共表达式createAddition(表达式左、表达式右、SourceLocation SourceLocation){
加法表达式=新加法(左、右);
返回表达式;
}
}
但应该是这样的:

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;
        }
}
类MyImplementation实现接口{
@凌驾
公共表达式createAddition(表达式左、表达式右、SourceLocation SourceLocation){
加法表达式=新加法(左、右);
返回表达式;
}
}

这是原始类型
Expression=|Expression
。在方法参数中使用简单的
表达式
,可以擦除类型参数。您不能在接口实现中声明原始
表达式
并使用带类型参数(CTE)的参数重写方法。将类型参数视为简单别名。

如果显式参数化接口中的所有参数:

public interface IProgramFactory<T> {
  public Expression<T> createAddition(
      Expression<T> left,
      Expression<T> right,
      SourceLocation sourceLocation
  );
}
公共接口IProgramFactory{
公共表达式创建添加(
表情左,
表达权,
源位置源位置
);
}
然后你可以做:

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;
  }
}
公共类ProgramFactory实现IProgramFactory{
@凌驾
公共表达式创建添加(
表情左,
表达权,
源位置源位置
){
表达式expr=新添加的内容(左、右);
返回表达式;
}
}

是的,而且我已经在我的应用程序中使用了这种结构。这很奇怪,因为
Expression
肯定不会进入
Expression
,所以这一行
Addition expr=new Addition(左、右)不应编译。表达式类是genericYes generic,因此我可以处理任何类型的数据。喜欢收藏。如果在泛型中显式地提到该类型,那么它将不接受其他类型。如果您给出“?”则它将接受任何类型。请参阅通配符泛型文档和Java规范,但本例中的返回值应为expression缺少重要位,前两个代码段(
ProgramFactory
和实现类)的接口和类声明这里的问题是表达式是泛型的,并且实现使用多种类型的表达式,因此我不能将表达式作为参数放在interface@Goatherder95你应该真正描述一下你的设置和你想要达到的目标,因为这看起来非常像。如果是这样,并且您确实需要这样的实现,那么您可以声明
接口createAddition(Expression left、Expression right、SourceLocation SourceLocation)
也可以像
一样绑定它。这里通配符的问题是,您可能需要所有三个(left、right和返回值)为相同类型,而通配符则不是这种情况。