Insert generic type (10 second job)

hi again… could someone with cvs access spend 10 seconds (literally) doing this:


public class GameStateNode<G extends GameState> extends GameState {
private List<G> fixme;
}



thanks. It uses a parameterised list anyway, so why not extend it?

EDIT:
will need to re-specify to GameState here:

public class GameStateManager extends GameStateNode<GameState>

Added

Ugh, I kind of wish this hadn't been added.  I can see of VERY few instances of where this could be useful and the rest of the time it's going to just be extra code.  I think you're better off living with a cast.

How does it hurt?

Because now you get warnings if you don't do:


GameStateNode<GameState> gsNode = new GameStateNode<GameState>();



You'll get warnings now if you try to use:

GameStateNode gsNode = new GameStateNode();



It doesn't matter much, but as limited of cases where using generics is beneficial for the GameStateNode I think it's adding extra coding requirements on people that do not find it useful but still care about compile-time warnings.

IMHO, an API should either go for generics in every place, or none at all to keep it consistent. This issue of Java 1.4 Vs Java 1.5+ has been roaming in my head for quite a while (at least when talking about jME) but had not find the courage to bring it up.



I think right now jME is essentially 1.4 style. While some features in 1.5 style are certainly desirable, (like enums instead of static final ints for many setters, getters) I think jME can survive without making the leap to 1.5. Now, if the devs decide to make the leap, (which I personally think might be a good idea overall), understand this is a very time consuming task.



Pros:


  • It would be fully compatible with newer JDKs

  • It would solve many reference problems using the wrong final int in a method call

  • Some new features are really sweet (like automatic encapsulation)  :D



Cons:

  • It would mean a major face lift to the whole API

  • Many calls would have to be changed, and it is likely this would take some time to fully convert

  • Bugs are likely to occur on a change this size, and with v1.0 getting closer and closer, might not be worth the risk



Hope someone has input in this issue.

A more complete switch-over to many 1.5 features is planned for jME, particularly enums.  We already use generics in a number of places.  It would be good to get more feedback as we get past the 1.0 release.

Generics, enums, varargs and love…

The more clarity and accuracy and fewer development bugs the better…


duenez said:

IMHO, an API should either go for generics in every place, or none at all to keep it consistent.


No offense, but such a statement I think shows a lack of understanding of generics.  Generics in every place would be ridiculous as practically everything can be "generified" but very few things really benefit from such a thing.  I learned a fine lesson quite recently about this myself.  In jSeamless I decided that it made sense to define generics for the children of containers but every Component also has the ability to define generics for an arbitrary associated Object so the Container looked like this:

public class Container<T extends Component<?>, O>



There were actually very few places where it made sense to define the types of children that were going to be added to that Container.  Sure there were some benefits, but you often ended up just trying to do what you had to in order to use it:

Box<Component<?>, Object> box = new Box<Component<?>, Object>();



And if you were crazy you could do things like:

FlowBox<DividedBox<Box<Box<Label<String>, Object>, Object>, Object>, Object>, Object> crazyContainer = new FlowBox<DividedBox<Box<Box<Label<String>, Object>, Object>, Object>, Object>, Object>();



It just wasn't practical and people were complaining because of all the extra code they had to type in just to keep compiler warnings from appearing in cases where they just wanted a container to add components to.

I'm a big fan of Generics and think they can be very useful, but should only be used where they make sense.  We don't need to complicate the API with a bunch of useful features just for the sake of being able to say, "we've gone crazy with generics".  :P

@Darkfrog: I am extremely offended by your comment  :smiley: Not because you said having generics everywhere would be st00pid, but because you though I really meant everywhere  :stuck_out_tongue:



What I meant to say is: having generics everywhere where they are needed (for example, in the java.util.* classes that already use generics). I meant to say that having two significantly different coding styles, some using generics for encapsulation of… well… generic types, and some using general objects to store them is confusing and a poor coding strategy.



I am a mild fan of generics, because they really come in handy when you don't need to cast stuff around always, but consider the added <class> tags cumbersome at times. In summary, I think generics are the least of the cool stuff in 1.5+ code style, but if you introduce them, you might as well use the other cool stuff since that is breaking compatibility anyway.



Hope this clarifies the issue.

We already force 1.5+ JRE anyway, so it's not a big deal.  :stuck_out_tongue:



The real discussion though is figuring out where generics are useful in jME.

darkfrog said:

The real discussion though is figuring out where generics are useful in jME.


To me, the absolute real discussion is replacing the constants with enumeration types and varargs ;). As far as generics is concerned, I would say whenever the (non-nested) storage of data types is required, and the types are broad enough.  :| A very decisive method to figure it out, right? 

I guess there are several places in the API where covariant return types (which were introduced in 1.5 because of Generics) should be used.



I mean things like this:



interface F {

Landei said:

I guess there are several places in the API where covariant return types (which were introduced in 1.5 because of Generics) should be used.

I mean things like this:


interface F {
   Shape getShape();
}

class C implements F {
     Box getShape() { 
     return new Box();
  }
}




Do you mean:


public interface ShapeReturner<F extends Shape> {
   F getShape();
}

public class BoxReturner implements ShapeReturner<Box> {
     Box getShape() { 
     return new Box();
  }
}



?

No, this is one of the rare cases where I meant what I wrote.



You can use covariant return types with generics (that's why they were introduced), but you don't have to.



Covariant return type means that it's allowed to return a subtype when you override/implement a method from your base class/interface. Or maybe you prefer this description:



Java Language Specification

8.4.5 Method Return Type
The return type of a method declares the type of value a method returns, if it returns a value, or states that the method is void.
A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:


If R1 is a primitive type, then R2 is identical to R1.
If R1 is a reference type then:
R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (

Sorry about the offtopicness, but isnt it ironic how a thread marked as "10 second job" has two pages whereas most of the heavily involved threads or threads involving important and complex tasks manage to stay on one page?

well changing one line is a 10 seconds job.

But keeping the source of a big project like jME uniform and well structured isn't.

So, such changes have to be discussed well.

It was just an idea…  ://

wait till I post my next one… }:-@