Force the same type in java generics implementing an interface

having:

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

      

Lets me pass a different type to a

and b

if both implement an interface Foo

.

I think it would be better said 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 interface Foo

)?

+3


source to share


2 answers


The following is a little ugly, but it 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 from what you want, because it allows the second parameter to subclass the first. I think it's ok because S

- it is T

, so it should work wherever it is T

.

0


source


If you have control over 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 types are defined Enum

. However, it allows the second parameter to be a subclass of the first.

0


source







All Articles