1

I'm trying to implement a graph using generics, and I want to use a generic argument for both the nodes and the data within the nodes. It works if I do it the first way, but ideally I would like to define it the second way.

Why doesn't the second way work?

//OK
public class AdjacencyListGraph<E, N extends Node<E>> {
}

//Cannot resolve symbol E
public class AdjacencyListGraph<N extends Node<E>> {
}
2
  • How do you want to use the type parameters in methods? Commented Apr 20, 2018 at 13:53
  • Internally, N is a param when adding a node and a return type when querying nodes, and E maps nodes in a hash map and is used to query the graph. Commented Apr 20, 2018 at 14:07

1 Answer 1

2

In the context of java generics the word extends means the upper bound, not the inheritance. The meaning of that word is overloaded in case of generics.

Generics were introduced in java to give developers the ability to write more consistent, clean and less buggy code then it was before. It's all about the development, not the execution. There are no generics in the compiled code. However there is some information about actual types in metaspace which you can retrieve via reflection, but it's meta information, not the actual code.

During the compilation generic types are erased and replaced by actual bounds (https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html). And here is the root cause of your problem. If a provided bound is also generic then compiler is unable to perform type erasure. It simply dont know by which type it should replace the generic one in the code during compilation. So you will get compilation error.

//OK
public class AdjacencyListGraph<E, N extends Node<E>> {
}

Here anyway you will have to provide actual type E and so the compiler will be able to resolve the actual bound and perform type erasure.

//Cannot resolve symbol E
public class AdjacencyListGraph<N extends Node<E>> {
}

In this case your bound also becomes generic. The compiler do not know the actual type. It can be any type. So it cant perform type erasure here and gives you a compilation error.

Also here are some useful resources about generics: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html https://docs.oracle.com/javase/tutorial/java/generics/index.html

The first one is really great. Here is info about extends word and it's meaning in the generics context: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Does%20extends%20always%20mean%20inheritance?

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the great explanation. Is this something that could be implemented as a part of generics on the future or is it more involved than I presume?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.