简体   繁体   中英

force exact same type on java generics implementing interface

having:

public <T extends Foo> int(T a, T b) { }

Allows me to pass in a different type in a and b , if both implement the Foo interface.

I think this would be better stated as:

public <T extends Foo, U extends Foo> int(T a, U b) { }

My question is: is there a way to achieve the first signature (that both a and b are the same type and that both implement the Foo interface)?

The following is a bit ugly but works.

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
  }
}

This is a little different than what you want because it allows for the second parameter to subclass the first. This I think is OK because S is a T so it should be able to work wherever a T does.

If you have control of the classes, you can do this

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

This is similar to how Enum types are defined. However, it allows the second parameter to be a subclass of the first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM