aspose file tools*
The moose likes Beginning Java and the fly likes Java Generics Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Java Generics Problem" Watch "Java Generics Problem" New topic
Author

Java Generics Problem

leroy tsruya
Ranch Hand

Joined: Sep 24, 2009
Posts: 57
Hi all!
I have a question about generics.
I am trying to create a generic state machine.
so these are the classes:


The problem is with SampleChild1 class.
whenever I try to pass a SampleChild1State1 Object into the setState method of BaseClass I get the following error:
The method setState(State<capture#2-of ? extends BaseClass>) in the type StateMachine<capture#2-of ? extends BaseClass> is not applicable for the arguments (SampleChild1State1)


Is there anyway to solve this problem? to make my StateMachine class generic so I can declare it only in BaseClass?
Or I will have to have a new specific Object of StateMachine class in any subclass of Baseclass?

Thanks!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19783
    
  20

Shouldn't SampleChild1 extend BaseClass?


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
leroy tsruya
Ranch Hand

Joined: Sep 24, 2009
Posts: 57
Wow.. what a dumb mistake..
Thanks a lot Rob Prime.
it should extend it.



It was a mistake when I typed the post into the site..
I edited the original post as well
Thanks..
Virendrasinh Gohil
Ranch Hand

Joined: Jun 09, 2004
Posts: 46
leroy tsruya wrote:

Many problems with this sample.

1. SampleChild1State1 is interface? If so, it must extend State interface if not, must defined as class
2. SampleChild1 must extend BaseClass (as State interface can only accept <T extends BaseClass>)


3. The setState method is expected to accept object of StateMachine of type T which extends BaseClass only. Whereas, you are trying to pass SampleChild1State1 which is (if a class) implementation of State itself.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19783
    
  20

Leroy, please PostRealCode. You may choose to omit parts that aren't necessary, but with your current code I have to fix too many compiler errors before I get to the error you get (actually I'm not even there yet).
leroy tsruya
Ranch Hand

Joined: Sep 24, 2009
Posts: 57
Rob Prime, once again you are right..
really sorry for the inconvenience...
Here is the code I have, I omitted unrelevant stuff:



This is what I get:
The method setCurrentState(EntityState<capture#2-of ? extends BaseGameEntity>) in the type EntityStateMachine<capture#2-of ? extends BaseGameEntity> is not applicable for the arguments (ItemUnidentifiedState)
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19783
    
  20

OK, now I could pinpoint the exact location of the error.

"this.states" is an EntityStateMachine<? extends BaseGameEntity>. And that wildcard is the problem. EntityStateMachine<T> expects a T for its setCurrentState method. However, what is T in this.states? You don't know. It could be BaseGameEntity, InfObject, or anything else that extends BaseGameEntity.

I suggest you make BaseGameEntity generic as well. The class definitions then become as follows:
One more change is required, in BaseGameEntity:
This now matches the initialization of states inside Item:
After these changes I could compile your code.
leroy tsruya
Ranch Hand

Joined: Sep 24, 2009
Posts: 57
Wow! Thanks Rob!
It compiles now! No errors at all
However, can you please explain what that line of code means:


And also, if I may.. Is that the best way to do it?
Or, did I complicate it more than it should be?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19783
    
  20

The other alternative is to use I haven't tested if that would compile. If so, that would actually be easier.

As for that line. The T is the new generic type, as usual. Because you had "? extends BaseGameEntity" the T must be bound as well. That would lead to "T extends BaseGameEntity". However, BaseGameEntity is now generic, so the compiler will complain about a raw type. You must fill in the generic type. There are actually more alternatives:
- BaseGameEntity<?> -- any BaseGameEntity is allowed. This would allow Item to extend InfObject<BaseGameEntity>, InfObject<InfObject>, InfObject<Item>, or any other sub class of BaseGameEntity.
- BaseGameEntity<T> -- Item can only extend InfObject<Item>
- BaseGameEntity<? extends T> -- Item can only extend InfObject<Item> and InfObject<X> where X is any sub class of Item
- BaseGameEntity<? super T> -- like ? but limited to BaseGameEntity, InfObject and Item
- BaseGameEntity<X> with X being a hard coded class. You definitely do not want that though.


I think that trying out to remove the "? extends" from states would actually be worth checking out. It will make your classes less complex.
leroy tsruya
Ranch Hand

Joined: Sep 24, 2009
Posts: 57
Thanks all for the help, especially Rob, you have been a great help for me.
It works perfect now, and I updated other classes I wrote.
Unfortunately, your suggestion seems the only way the code will compile.
Thanks a lot
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Java Generics Problem