3

With the below code, I get a compile error "Incompatible types - found Tree<T> but expected Tree<T>". Any idea what I'm doing wrong with the generics? Any other way to access the parent object of an object other than ParentObjectClass.this? I am aware of the "workarounds", like adding a variable to the Node class that points to its parent object. Also, I could pass myInt as a constructor parameter, but I'd like to find a nicer solution. Thanks for any suggestions.

I came across a similar question on this site, but I tried it for my code and couldn't get it to work: Access "this" from Java anonymous class.

public class Tree<T> implements TreeIF<T> {
    private int myInt;
    Node<T> root;

    ...

    // a constructor
    public Tree(Node<T> root) {
        this(root.getTree().getMyInt()); // call to different constructor
        this.root = root;
    }

    ...

    // a method
    public int getMyInt() {
        return myInt;
    }

    ...

    // inner class
    class Node<T> {
        T element;

        ...

        Tree<T> getTree() {
            // return Tree.this;     // I tried this too, but it didn't work
            **return Tree<T>.this;** // HERE'S THE COMPILE ERROR
        }
    }
}

Thanks for the suggestions, Jon. And, yes, you're right, the T of the Tree class is the same as the Node class. The tree actually contains nodes, with the nodes containing the element. The Tree class already knows that it uses the Node class, so no type parameter is needed for that. The type parameter is basically a pass-through. I would just get rid of the type parameter for Tree altogether, but the interface (which I cannot modify) returns T in a couple of its methods, so it needs to know what T is. I tried changing to E and compiling...I did not get the same error, yet, but I got an error in a different part. I'll have to root out the other error and then see what happens. In the mean time, any further suggestions?

Community
  • 1
  • 1
Nnn
  • 31
  • 2

2 Answers2

5

You've introduced a new type parameter, also called T. If you change this:

class Node<T>

to this:

class Node<E>

the error will be clearer. However, I suspect you actually want this:

class Node

After all, the T of the node is really just the T of the tree, right? In other words, you want a (say) Tree<String>.Node - it wouldn't make sense to have a Tree<String>.Node<Object>.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

This works:

public class Tree<T> {
    private int myInt;
    Node root;

    ...

    // a constructor
    public Tree(Node root) {
        this(root.getTree().getMyInt()); // call to different constructor
        this.root = root;
    }

    ...

    // a method
    public int getMyInt() {
        return myInt;
    }

    ...

    // inner class
    class Node {
        T element;

        Tree<T> getTree() {
            return Tree.this; // leave out <T>
        }
    }
}
herman
  • 11,740
  • 5
  • 47
  • 58