Understanding "improperly formed type, type arguments given on a raw type" when using typed inner class outside outer class
Asked Answered
K

2

6

I am a little bit confused with the following and would be thankful for help.

What I wanted to do was implement a generic circular list where I can get access to the nodes (not their values) from outside. I will try to give a minimal setup which illustrates that.

class CircularList<T>{
    Node<T> first;
    /*Implementation details..., getters, setters */
    public Node<T> getFirst(){ return this.first };

    public class Node<U>{
        /*...*/
    }
}

Usage in another class:

CircularList<Vertex> vertices = new CircularList<>();
/*...*/
Node<Vertex> vertex = vertices.getFirst();

In the last line it says type arguments given on a raw type, which I don't really understand. I don't understand how this is a raw type. I thought through the type parameter of CircularList and the fact that getFirst returns a Node that the type wouldn't be raw but I obviously am mistaken.

Kayleigh answered 12/6, 2018 at 9:0 Comment(2)
Glad you got a complete answer. Still an interesting question!Blade
Thank you! To be honest I am not satisfied how it "looks" at the end of the day. I feel the language should make something like this simpler but deriving from the answers of you two I think I begin to understand that it would lead to constructions which are not very understandable by reading the code due to the implicit reasoning that has to be done. It seemed just odd to me that the remaining options from my point of view were: make the inner class static OR uglify the using business-code. Both options leave a bad taste for me, probably my design is just bad...Kayleigh
B
6

You didn't specify the argument to CircularList:

CircularList<Vertex>.Node<Vertex> vertex = vertices.getFirst();

UPDATE

But this doesn't make a lot of sense: you should either declare class Node<U> as static, or not specify any argument to it (and use argument T of the enclosing class).

Blastosphere answered 12/6, 2018 at 9:7 Comment(1)
Ok, I see that would solve that but I agree that it is kinda ugly. I will try refactor that. As I understand there is no way to use typed Node<Vertex> outside the list if I don't go for the static version, because I wouldn't be able to use it if I removed the type-parameter entirley from the inner class's signature?Kayleigh
B
2

Here:

public class Node<U>{

Should rather say Node

You already have a generic type T in your class; and obviously a CircularList of Ts should only hold Nodes of T.

Basically you introduced another, second type parameter. Which adds nothing but "confusion". Also note that your inner Node class isn't static, so there is nothing from preventing you of saying that instances of Node are generic in T, like the enclosing list class.

Your code added a second generic parameter for no reason at all.

Blade answered 12/6, 2018 at 9:4 Comment(3)
If it's not a static class, it automatically uses the type parameter of it's enclosing class. Re-declaring with Node<T>{ hides the outer generic type parameter. Instead, only Node{ must be used; the type parameter T will still be available in the inner class.Jowers
Using T as the inner type parameter was what I first did, which is why I changed it to U to be more precise that it is not necessarily the outer type but merely shadowed. Odly, turning the inner class to static removed the error but as I understand that introduces the possibility of instanciating a node without a corresponding list which i don't want. Any suggestions on that?Kayleigh
Removing the inner type paramter didn't change the error :/Kayleigh

© 2022 - 2024 — McMap. All rights reserved.