Java 令人惊讶的是,这个程序的v1可以编译,而不是v2。这是故意的吗?若然,原因为何?

Java 令人惊讶的是,这个程序的v1可以编译,而不是v2。这是故意的吗?若然,原因为何?,java,generics,inheritance,covariance,Java,Generics,Inheritance,Covariance,第一版: public interface DeepCopyable<T> { T deepCopy(); } public interface Statement extends DeepCopyable<Statement> { } public interface Expression { Expression deepCopy(); // forgot I have an interface for this } public class Invoc

第一版:

public interface DeepCopyable<T>
{
  T deepCopy();
}

public interface Statement extends DeepCopyable<Statement>
{
}

public interface Expression
{
  Expression deepCopy(); // forgot I have an interface for this
}

public class Invocation implements Expression, Statement
{
  public final String Field;

  public Invocation(String field)
  {
    Field = field;
  }

  public Invocation deepCopy()
  {
    return new Invocation(Field);
  }
}
public interface Expression extends DeepCopyable<Expression>
{
}
公共接口可深度复制
{
T deepCopy();
}
公共接口语句扩展了DeepCopyable
{
}
公共接口表达式
{
表达式deepCopy();//忘记我有一个用于此的接口
}
公共类调用实现表达式、语句和
{
公共最终字符串字段;
公共调用(字符串字段)
{
字段=字段;
}
公共调用deepCopy()
{
返回新调用(字段);
}
}
第二版,更新表达式界面:

public interface DeepCopyable<T>
{
  T deepCopy();
}

public interface Statement extends DeepCopyable<Statement>
{
}

public interface Expression
{
  Expression deepCopy(); // forgot I have an interface for this
}

public class Invocation implements Expression, Statement
{
  public final String Field;

  public Invocation(String field)
  {
    Field = field;
  }

  public Invocation deepCopy()
  {
    return new Invocation(Field);
  }
}
public interface Expression extends DeepCopyable<Expression>
{
}
public接口表达式扩展了DeepCopyable
{
}
但是现在我得到了编译错误

Error: C:\temp\Invocation.java:1: DeepCopyable cannot be inherited with different arguments: <Expression> and <Statement>
错误:C:\temp\Invocation.java:1:DeepCopyable不能用不同的参数继承:和

在返回类型不变的一般情况下,我可以理解这个错误消息;但是,如果我用返回类型A和B两次继承同一接口,而且实现方法返回C,其中C是协变wrt A和B,这难道不安全吗?

在调用类中,您扩展了两个接口表达式和语句,在代码的第二个版本中,所发生的是表达式接口正在扩展DeepcCopyable接口,如下所示

class Invocation implements Expression, Statement {...}




interface Statement extends DeepCopyable<Statement> {
}

interface Expression extends DeepCopyable<Expression> {
}
类调用实现表达式、语句{…}
接口语句扩展了DeepCopyable{
}
接口表达式扩展了DeepCopyable{
}

在您的代码中,发生的是当您实现两个接口表达式和语句,该接口表达式和语句扩展到不同的泛型时,这里发生的是编译器会混淆要考虑的内容,因此它将不允许实现接口表达式。语句。不能使用不同的参数两次实现接口。这就是第二个版本的问题


第一个版本的问题是,它的两个接口都使用略微不同的签名指定
deepCopy
。但是,它实现的签名与这两个版本都兼容,因此没有问题。

请发布第二个版本的完整代码,因为我没有收到任何编译错误。