Generics: factory method for returning parameterized instance

A

allen

Hi,
While generics ought to be saving me time, I'm spending far more time
trying to figure it out than I can afford!
Here we go. I want a factory method for creating new instances of a
known base class given the class name. Then I want to call that factory
method, expecting a parameterized instance in return.

basic factory method, ignoring exceptions:

public static <T> T create( Class<T> base, String classname ) throws
Exception
{
Class<? extends T> clazz = Class.forName( classname ).asSubclass(
base );
return clazz.newInstance( );
}

this works for simple objects:
java.awt.Component c = create( java.awt.Component.class,
"java.awt.Button" );

But now I want to create a parameterized instance:
List<String> list = create( List.class, "java.util.LinkedList" );
which gives me the unchecked cast warning. Obviously the String type is
not being handed in anywhere, but trying create( List<String>.class,
"ja...") doesn't compile.

How do I declare my factory method to handle both cases with no
warning? I'm trying to work out the "correct" way, so ideally I don't
want to @Suppress anything.
Thanks
Allen
 
I

Ian Pilcher

How do I declare my factory method to handle both cases with no
warning? I'm trying to work out the "correct" way, so ideally I don't
want to @Suppress anything.

I don't believe that there's any way to avoid the cast, and the
consequent warning. Also note that Sun's javac (1.5.x) doesn't actually
pay attention to the @SuppressWarnings annotation.

(If you think that this is asinine, you're not alone.)
 
J

John C. Bollinger

basic factory method, ignoring exceptions:

public static <T> T create( Class<T> base, String classname ) throws
Exception
{
Class<? extends T> clazz = Class.forName( classname ).asSubclass(
base );
return clazz.newInstance( );
}

this works for simple objects:
java.awt.Component c = create( java.awt.Component.class,
"java.awt.Button" );

But now I want to create a parameterized instance:
List<String> list = create( List.class, "java.util.LinkedList" );
which gives me the unchecked cast warning. Obviously the String type is
not being handed in anywhere, but trying create( List<String>.class,
"ja...") doesn't compile.

How do I declare my factory method to handle both cases with no
warning?

It cannot be done, at least not at the level of generality you describe.
In particular, reflective instantiation of a generic class will
always require a minimum of one unchecked cast to get a properly
parameterized reference. This is because with reflection you can only
ever instantiate a "raw" class. In fact, that's all you ever do by any
means, but when you use the new operator with an appropriate type
parameter list you're giving the *compiler* (i.e. not the VM) some extra
information about how you want to use the object.
 
R

Roedy Green

but trying create( List<String>.class,
"ja...") doesn't compile.

List is in interface not a class, so it is impossible to create a new
instance of it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top