Martin Vajsar wrote:So you need to access the instance of the outer class? See ....
I can access the instance of the outer class. That is not the problem. In plainer language: the inner class implements ListIterator<T>, therefore its next() method must return an item of type T. I want to get this by calling get(), which implicitly belongs to the outer instance (a LinkedList derived object) and returns an item of type T. But the compiler says the T of the inner instance cannot be considered the same as the T of the outer instance, therefore I cannot meaningfully make use of the access to the outer instance -- instead, I have to pass it in and work with that reference:
Using list.get() works, because the compiler is fine with the fact that it returns type T. But if I just use get() (method of the instance of the outer class) the compiler sees it as a type mismatch, so I cannot make meaningful use of that access. The "inner class" might as well be a completely separate class. Make sense?
By declaring your iterator class as CircularIterator<E>, you're introducing a new type parameter E, which, though it has the same name, has no relation to the type parameter E of the outer class. So the solution is to simply not declare the parameter in the CircularIterator class definition; that way the E (which is valid throughout the source code, including any inner classes) will be the E of the outer class.
You might want to try to take a look at the LinkedList source, to see how it is handled there.
Joined: Jan 04, 2012
Martin Vajsar wrote:So the solution is to simply not declare the parameter in the CircularIterator class definition; that way the E (which is valid throughout the source code, including any inner classes) will be the E of the outer class.
That works, I just get a bunch of "unchecked conversion" warnings I guess I need to suppress. The constructor is private, so that shouldn't matter.
I haven't tried it, but can you declare CircularIterator implements ListIterator<T>? It feels like that ought to be allowed, because the CircularIterator always sits within a CircularList<T>. And if it works you've got a fully generic solution and you won't get the warnings.
The line 27 of your code should look like this instead:
This is the way to "force" the outer T parameter over the CircularIterator class. You'll have to change a few method declarations inside the inner class to take/return T instead of Object, but then it should compile without warnings.
It should not take much time to understand what's happening here. Once you do, you'll understand generics a tad better again.
Joined: Jan 04, 2012
"CircularIterator implements ListIterator<T>" did the trick, thanks gang.
Martin Vajsar wrote:You'll have to change a few method declarations inside the inner class to take/return T instead of Object,
Actually, the issue there was that add(T) clashed with the outer class's add() method, whereas add(Object) did not but still satisfied the ListIterator interface requirement. Interestingly, this last change seems to have mitigated that problem as well -- now add(T) is fine. Not quite sure why that would make a difference but