• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generics and Casting  RSS feed

 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I am getting this error "Type mismatch: cannot convert from Object to E" in the last line of the pop() method.

I don't understand why that error occurs despite item being declared as type E in the Node class. Why do I have to make an explicit cast in this instance?
 
Paweł Baczyński
Bartender
Posts: 2074
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's because E in Node is not the same thing as E in Stack.
The compiler do not see the connection.
You declared your nodes inside Stack class as raw Node.
That means that all methods of Node class that should return E will return Object and all fields of type E will be in fact of type Object.
Declare all your nodes declarations (in fields and methods) inside Stack and Node as Node<E>.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Pawel. Even if I have an inner class Node<E> inside Stack, I still get this error; but if I just have the inner class as Node without the generic type, then the error goes away which is in line with what you've said. Even Node<E> is an inner class of Stack, is the E in Node different from E in Stack?

So, if I want to have my Node class separate, is casting the only way here? And is this an acceptable way of doing this?
 
Paweł Baczyński
Bartender
Posts: 2074
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you tried declaring your fields as Node<E>?
For example have you changed line 6 of Node class from:
Node next;
to:
Node<E> next;
?

You have made your classes generic. That's nice.
But you need to actually use this generic types.

Prasanna Raman wrote:So, if I want to have my Node class separate, is casting the only way here?

First, why would you want Node to be separate class. As far as I can see it is an internal of your Stack. Why do you want it to be seen outside?
Second, you do not need to use casting if you declare your variables and methods correctly.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, it was a typo. I've made my next variable in my Node class to be Node<E> next, but that hasn't changed anything.
 
Paweł Baczyński
Bartender
Posts: 2074
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you post your current code so I can check it?

EDIT: I checked your code from first post and made some changes.
Remember I said you need to redeclare all nodes as Node<E>?
Make sure you change all. Including method local variables like nodeToBePopped.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem was with this line:I've changed it to Now there's no error, but how does the compiler now know that the E in Node and Stack are the same?
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The E in Node and Stack are not the same. But in your Stack class, you declare variables of type Node such as



That tells the compiler that you want to use a Node instance that works with the type E, the same type your Stack instance is working with. So if you create a Stack<String> the Stack will use a Node<String>.

You could change the Node class so that the generic type parameter was called T, or any other valid name, and it wouldn't matter. That is just a placeholder for the real type that is used when you declare instances of Node.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paweł Baczyński wrote:Second, you do not need to use casting if you declare your variables and methods correctly.
I am having a Node class separately because I might want to use the same class to implement a Queue or something else later.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Mike. I know it's best to keep the fields private. Currently, the fields in my Node class are package private. How do I manage to keep the next and item variables private in Node and still do what I'm doing in Stack?
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You will need to provide methods to access the fields.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, but that still doesn't solve the problem of someone trying to modify the contents of the Stack, correct? Is the only way to achieve this is by having an inner class?
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your Stack is not returning a Node anywhere that I can see. Nothing can alter the contents of the Nodes in your Stack if they don't have access to the Nodes.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, is it OK leaving the variables as package private in this case?
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's ok in the sense that no classes external to the Stack can access the Nodes it is using.

It is best practice to make all fields private and provide methods to access them though.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!