Java generic type

When i have an interface

public interface Foo<T> { T someMethod(); } 

Is there a way to ensure that when some class implements this interface, then the generic type is the same implementation class.

For instance:

 public class Bar implements Foo<Bar> { Bar someMethod() { return new Bar(); } } 
+4
source share
4 answers

Yes, it can be done (sort of, see below). (In the C ++ world, this is called a " Curiously Repeating Pattern Template ", but it also applies in Java):

 public interface Recur<T extends Recur<T>> { // ... } 

(Note the second mention of T This is an important part of CRTP.)

It is also a java.util.Enum definition, so an enum type called Foo must be inferred from Enum<Foo> , so it is also not an unusual template in Java.


I would like to say that the above is the end of the story, but the tangent rightly indicates in its revision that it is not completely stable and indeed not everything that differs from their answer in character.

There is one difference (I can think of) between the Recur<T> solution that I have and the Recur<?> Solution that has a touch:

 public interface Recur<T extends Recur<T>> { T foo(); } class A implements Recur<B> { @Override public B foo() { return new B(); } } class B implements Recur<A> { @Override public A foo() { return new A(); } } 

With <T> above will not compile; with <?> that would be. But this is just splitting hair; it does not change the center point of the tangent, which is specified by an existing Recur implementation, you can make subsequent implementations a used existing type, and not by itself. I still say that it costs something, but it does not cost more than tangent.

In conclusion, let's answer and, if you can, answer. (tangents, you must touch your message so that I can also promote you). They have a very good moment, and I'm sorry that I missed it for the first time. Thank you tangents!

+21
source

No, you cannot reference the implementation class. The best you can do is:

 public interface Foo<T extends Foo<?> > { T someMethod(); } 

By doing this, you can be sure that someMethod() returns an object that implements Foo .


EDIT:

Even with an interface definition as follows:

 public interface Foo<T extends Foo<T > > { T someMethod(); } 

You can define the class Bar2

 public class Bar2 implements Foo<Bar2 > { @Override public Bar2 someMethod() { return new Bar2(); } } 

And then you can define the class Bar , which implements Foo , but does not return Bar , but Bar2 :

 public class Bar implements Foo<Bar2 > { @Override public Bar2 someMethod() { return new Bar2(); } } 

The original question was that you could prepare to use an interface like Bar .

And the answer is: No.


EDIT:

Angelica Langer gives a good explanation How to decrypt "Enum <E extends Enum <E β†’" "" <> <

+12
source

This is not possible due to the type of Erasure .

EDIT:

I voted, here are more explanations:

 public interface Foo<T>; 

T on top is available at run time, so it cannot be checked. However, one could use a custom annotation that could ensure its implementation.

0
source

I can’t imagine a simple no. on this site (too short organ), so here it goes.

Not.

-3
source

Source: https://habr.com/ru/post/1299781/


All Articles