Search code examples
javagenericstypesinitializationinner-classes

Can't access generic state type outside class


When trying to compare keys when implementing merge sort on a linked list I found that Java seems to hide generic types of fields from outside the class, and you have to either cast a variable to the generic type (even when it is of the generic type itself), or make an instance of the class that uses generics and then access the field from there

public class LinkedList<Item extends Comparable<Item>> {
    private Node<Item> head;
    
    public static class Node<Item> {
        public Item key;
        public Node<Item> next;
    }

    public LinkedList() {
        head = null;
    }

    public LinkedList<Item> merge(LinkedList a, LinkedList b) {
        if (a == null || a.head == null) {
            return b;
        } else if (b == null || b.head == null) {
            return a;
        }
        LinkedList<Item> x = null;
        Item keyA = (Item) a.head.key;
        Item keyB = (Item) b.head.key;
        Node<Item> node = a.head;
        Item works = node.key;
        Item doesNotWork = (a.head).key;
        ...

In the code snippet above, keyA and keyB must have their values casted to the generic type Item. The node object of type Node can be used to reference its key which is of type Item, but trying to initialize doesNotWork results in the error "java: incompatible types: java.lang.Object cannot be converted to Item", even though it referenes the Node head object, and then the Item key object within it (with brackets too). Changing the access modifiers of the class or its fields makes no difference. Can someone explain why Java can't access generic types within classes despite being able to do so for concrete types, and if I can reference a generic type from outside a class without casting or making an instance of the class with the generic type?

No, this is not the same as the question about raw types because the answers to that do not tell me how I can directly reference a field of the static generic class. I know this is a terrible way to use generics, but the code given (apart from at the end) was from a lab in my algorithms class, I don't choose the code they give us. It's also not really fair that I didn't lookup raw types since I never really knew what they were. I can't edit the code template they gave us, please let me ask how I can do what I need to for this assignment instead of being a code snob.


Solution

  • From the logic of your list it is implied that both lists beeing merged must be of the same Item type - then you can type them and this will also avoid all the unnecessary casting.

    public LinkedList<Item> merge(LinkedList<Item> a, LinkedList<Item> b)