在实现接口的java泛型上强制使用完全相同的类型

在实现接口的java泛型上强制使用完全相同的类型,java,generics,Java,Generics,具有: 我的问题是:有没有办法实现第一个签名(a和b都是相同类型的,并且都实现了Foo接口)?下面的内容有点难看,但很有效 public <T extends Foo, U extends Foo> int(T a, U b) { } 公共类主{ 静态类Foo{} 静态类栏扩展了Foo{} 静态类Baz扩展了Foo{} 静态void foo(ta,sb){ 公共静态void main(字符串[]args){ foo(newfoo(),newfoo());//编译很好 foo(new

具有:


我的问题是:有没有办法实现第一个签名(a和b都是相同类型的,并且都实现了
Foo
接口)?

下面的内容有点难看,但很有效

public <T extends Foo, U extends Foo> int(T a, U b) { }
公共类主{
静态类Foo{}
静态类栏扩展了Foo{}
静态类Baz扩展了Foo{}
静态void foo(ta,sb){
公共静态void main(字符串[]args){
foo(newfoo(),newfoo());//编译很好
foo(new Bar(),new Bar());//编译很好
foo(new Bar(),new Baz());//编译器错误Baz没有扩展Bar
}
}

这与您想要的略有不同,因为它允许第二个参数对第一个参数进行子类化。我认为这是可以的,因为
S
T
,所以它应该能够在
T
的任何地方工作。

如果您可以控制类,您可以这样做

public class Main {

  static class Foo {}
  static class Bar extends Foo {}
  static class Baz extends Foo {}
  static <T extends Foo, S extends T> void foo(T a, S b) { }

  public static void main(String []args) {
      foo(new Foo(), new Foo()); // Compiles fine
      foo(new Bar(), new Bar()); // Compiles fine
      foo(new Bar(), new Baz()); // Compiler error Baz doesn't extend Bar
  }
}
公共静态类Foo{}
公共静态类栏扩展了Foo{}

公共静态类Baz扩展了Foo{} 公共静态无效剂量(ta,tb){ 最终钢筋=新钢筋(); 最终Baz Baz=新的Baz(); 剂量(巴,巴);//允许 剂量(巴,巴);//编译错误

这类似于
Enum
类型的定义方式。但是,它允许第二个参数是第一个参数的子类。

我认为没有。因此,您需要允许类型的上限和下限?我认为您必须依赖一些pos验证。我将创建一个注释
@SameType
,并验证某种拦截器中提交的类型。如果您尝试这样做,可能会重复,因为同一个Foo实现的两个实例可以相互交互,但不能与不同的Foo实现的实例交互,把事情做得和他们一样。代码>整数实现了
可比
双精度
实现了
可比
,您可以将两个
整数
或两个
双精度
传递给
void foo(可比a,可比b)
,但不能混合使用。这也允许允许某些类型的混合,比如传递
B
C
,如果两者都扩展
A实现了可比的
。我也想到了这一点,但是如果
Baz
扩展
Bar
,它会编译。注意到了差异,删除了注释。)foo(newfoo(),newbar())会编译,但我在回复中注意到了这一点。我认为Java中没有任何地方可以接受类型,但派生类型不能。派生类型的实例是基类型的实例,因此可以工作。这通常是需要的特性。我认为OP最担心的是兄弟姐妹被作为参数发送,而不是父子。如果您更改为Baz extends Bar,这也会编译。我认为没有办法解决这个问题。公共静态类Baz扩展Bar{}而不是公共静态类Baz扩展Foo{}是的,尝试过了,问题是如果你在客户端代码中执行
extends Foo
(no T),一切编译都很好。
public class Main {

  static class Foo {}
  static class Bar extends Foo {}
  static class Baz extends Foo {}
  static <T extends Foo, S extends T> void foo(T a, S b) { }

  public static void main(String []args) {
      foo(new Foo(), new Foo()); // Compiles fine
      foo(new Bar(), new Bar()); // Compiles fine
      foo(new Bar(), new Baz()); // Compiler error Baz doesn't extend Bar
  }
}
public static class Foo<T extends Foo<T>> {}
public static class Bar extends Foo<Bar> {}
public static class Baz extends Foo<Baz> {}
public static <T extends Foo<T>> void doSomething(T a, T b) {}

final Bar bar = new Bar();
final Baz baz = new Baz();
doSomething(bar, bar);  // Allowed
doSomething(bar, baz);  // Compile error