generics, factory methods and compiler warnings

Hi all,

I have a parametrized class where new objects are created via a factory. The problem is that I'm getting some compiler warnings. Am I missing something or there's no way to avoid them?

publicinterface Schedulable{

// methods here

}

publicclass Scheduler<Textends Schedulable>{

// should this be parameterized? If yes, how?

// (it's not possible to use T while <? extends Schedulable> gives problems)

privatestatic Scheduler scheduler;

private NodeManager nodes;

private DefaultServiceManager<T> services;

private Timer timer;

private LifecycleManager lifecycle;

publicstaticsynchronized <Eextends Schedulable> QueueScheduler<E> newInstance(){

if (scheduler ==null){

scheduler =new Scheduler();

scheduler.nodes = DefaultNodeManager.newInstance(scheduler);

scheduler.services =new DefaultServiceManager<E>(scheduler.nodes);

scheduler.timer =new Timer(scheduler);

scheduler.lifecycle =new LifecycleManager(scheduler,

scheduler.timer);

// these fields are initialized here and not into the constructor in order to avoid

// the 'this' reference to escape (see//http://www-128.ibm.com/developerworks/java/library/j-jtp07265/index.html

// for example)

}

// all the fields initialized above generate a warning

return scheduler;

}

protected Scheduler(){

// initialization of some fields here

}

// methods here

// methods here

}

Thanks,

Michele

[2962 byte] By [michele81a] at [2007-11-26 16:35:28]
# 1
That's because you create the Scheduler instance in a raw fashion. It should be:scheduler = new Scheduler<E>();
stefan.schulza at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 2
That is it.Every time declaring parametrized class variable(do not mix with class defenition)ClassName<T> variable;and instantiatingvariable = new ClassName<xxx>(...);where xxx -- actual type.
_Dima_a at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 3

I'm sorry, I forgot the type: the instance is actually created as you describe:

scheduler = new Scheduler<E>();

Is it possible, instead, that the problems arise because the static variable is declared without type?

private static Scheduler scheduler;

michele81a at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 4

Oops, sorry, didn't see the variable actually is a static, raw one. Here you will have a problem, as for once you cannot use the E for the static variable and second you could not guarantee that a previously created Scheduler would have the same type parameter as the one you are going to create:FirstSchedulable a = Scheduler.newInstance();

SecondSchedulable b = Scheduler.newInstance(); // would fail!

The second call would fail, as the first would have created an instance of Scheduler<FirstSchedulable>, which is stored in the static variable scheduler and not compatible to a Scheduler<SecondSchedulable>.

You should rethink you design.

stefan.schulza at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 5
No, I think the design is correct. In fact the scheduler is created only once (i.e. if the static variable is null).
michele81a at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 6

> No, I think the design is correct. In fact the

> scheduler is created only once (i.e. if the static

> variable is null).

No, it's not. As I said, if you try creating a parameterized scheduler from an inferred generic type, the design would only accidentally work, as long as you always have the same generic type being inferred (or raw usage). The example I wrote before shows when it will definitely fail.

If your Scheduler can only be of one specific type there is either no need to have it parameterized or you should not have a parametrized factory method.

stefan.schulza at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 7
Ok, now I see where the problem is. What do you suggest then?, just removing the parameter type?
michele81a at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 8

It depends on your application scenario, which I do not know (and surely will be out of scope to present here).

Do the users of the Scheduler need to parametrized it? That is, will there be places using the Scheduler requiring different arguments as E in the same VM/ClassLoader-Environment? If not, setting the Schedulers type parameter should rather be a configuration issue than a construction issue, i.e., the Scheduler retrieves the type information from some configuration provider.

Do you need separate Scheduler instances differently typed? In this case you should not use a singleton-like approach.

stefan.schulza at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 9

I think I fall into the first scenario you described since only one scheduler instance exists into my system.

Furthermore, the E type is propagated to several objects instantiated by the scheduler.

What do you mean by "the Scheduler retrieves the type information from some configuration provider"?, the type E is always a subtype of Schedulable.

michele81a at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...
# 10

The important question is: who decides about Type E and when? Configuration issue means, that E will be determined before running your application. For example by using a configuration file. Whoever has hands on that configuration should be the source for the Scheduler to retrieve or receive E.

stefan.schulza at 2007-7-8 23:00:19 > top of Java-index,Core,Core APIs...