22

Disclaimer: I don't have a whole ton of experience with Java Generics, but my colleagues and I just spent a solid hour trying to decipher an interface that was structured like this:

interface HasAttributes<A extends HasAttributes<A, B>, 
                        B extends HasAttributesType<B>> extends Identification<B> {

What exactly does it mean when an interface generic takes a type parameter that is itself? What does this do?

Adowrath
  • 701
  • 11
  • 24
Daniel Bingham
  • 12,414
  • 18
  • 67
  • 93
  • Could you also add at least a part of the body of the interface? – Zed Aug 25 '09 at 20:52
  • 2
    Uh, well and an explanation of what it does mean. Sorry for the frustration infused in the question, but you must understand the frustration that comes from trying to make sense of radically overcomplicated code. We had four experienced developers trying to make sense of this code that was written by our fifth man - an off site developer. None of us could make heads or tails of it. After an hour and a half. So needless to say, I was a wee bit frustrated when I wrote the question. – Daniel Bingham Aug 26 '09 at 11:49
  • 3
    `Interface` is not correct Java syntax – newacct Dec 29 '13 at 00:20
  • 3
    Have a read of Angelika Langer's great explanation: [Generics FAQ](http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206) I've also used this in my own code and had the same miscomprehension until I read Angelika's FAQ [My blog](http://tinyurl.com/pfws996) – Big Kahuna Apr 07 '14 at 15:21

1 Answers1

15

There is meaning to this - Java's Enum class is a good example of a simliar situation:

public abstract class Enum<E extends Enum<E>>
    implements Comparable<E>, Serializable

There are some enlightening answers in this Stack Overflow question about Enum that should shed some light on this particular use of generics for you, as well as answer this more elegantly than I could.

Community
  • 1
  • 1
Joshua McKinnon
  • 24,489
  • 11
  • 57
  • 63
  • 14
    "There is meaning to this" So, why don't you explain this meaning? – newacct Dec 29 '13 at 00:20
  • 1
    @newacct while it is custom to inline summary of link to the question I don't think copy-paste of the linked answer would be more valuable in this case (it is link to another SO question, so will have the same lifetime as this one)... Feel free to read and summarize linked answer here. – Alexei Levenkov Dec 29 '13 at 00:47
  • @AlexeiLevenkov: OK. The summary is: There is no reason to do it that way. Period. – newacct Dec 29 '13 at 01:15
  • @newacct I don't see it that way... To me it case of [curiously recurring template pattern](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) which have pretty solid reasons to exist. Note that I know nothing of Java (as I live in C# world) - so it pretty possible that equivalent of `ILinkedList : where T : ILinkedList { public T next;}` does not need exist in Java. – Alexei Levenkov Dec 29 '13 at 18:25
  • @AlexeiLevenkov: Interfaces cannot have fields in Java. But okay, we can change it to a method `T getNext();`. Nothing in that interface depends on `T` extending `ILinkedList`. If you changed it to `interface ILInkedList { ... }` it would compile just fine. – newacct Dec 29 '13 at 20:41
  • @newacct I think you trying to prove something different (i.e. that one can get away with less restrictions, similar to using just object for arguments/results). I.e. if one wants to make call on "second" item in the list `head.getNext().getNext().getClassSpecificInfo()` than it must be known that `getNext` returns type that is `ILinkedList<*>` and particular type. Indeed there are cases when such restriction is not necessary, but there is nothing in the question that clearly shows if it was not necessary. – Alexei Levenkov Dec 29 '13 at 22:03
  • @AlexeiLevenkov: There is no code in an interface. If a generic method or generic class wants certain properties of `T` (such as it extends `LinkedList`), then such can be specified where `T` is declared for that method or class. Also, `getClassSpecificInfo()` is not declared on the interface `ILinkedList`. Therefore, in order to use it, here the type argument of `ILinkedList` must be known at compile time (or some bound on it). So it *is* known what type it is. – newacct Dec 30 '13 at 03:41
  • Thanks. I hope you are right and this strange technic is of no use in Java (it is really confusing in any other language). On my attempted sample: `class Concrete implements ILinkedList { int getClassSpecificInfo() {...}; Concrete getNext{...}}` with restriction you can have single method `getNext` in interface returning `T` (which is guaranteed to be both `T` and `ILinkedList`) and you can have other generic methods taking `ILinkedList` to know that `getNext` returns `ILinkedList`; without restriction you need 2: `T getValue()` and `ILinkedList getNext()`. – Alexei Levenkov Dec 30 '13 at 08:12