JDK5 Generics

R

R

Hi All,

I'm new to Java, recently I've written my first pool and asked for
comments,
I got reply that I could use generics to create more independent pool.

But I have I problem with creating instance of the <T> type

on http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html
an example is given:

"
This is a generic method. It infers the value of its type parameter T
from its argument, and returns an appropriate instance of T, as
illustrated by the following snippet:
Author a = Othello.class.getAnnotation(Author.class);
"

But how can I write it using the generics?

I tried something like this:
pool.add(GenericPool.class.getAnnotation(<T>.class));
(in various forms i.e. T.class and so on - but without luck)

So my question is how can I instatiate a generic class?

thanks in advance for your help
best regards
R

here is full code of my GenericPool class:
class GenericPool <T> {
public static final int POOL_MAX_SIZE = 5;
private List<T> pool;
public GenericPool()
{
pool = new ArrayList<T>(GenericPool.POOL_MAX_SIZE);
for (int i = 0; i < GenericPool.POOL_MAX_SIZE; i++) {
// this is my problem I have to fill my pool with T classes
pool.add(GenericPool.class.getAnnotation(<T>.class));
}
}
public T get()
{
synchronized (pool) {
if (!pool.isEmpty()) {
return pool.remove(pool.size() - 1);
}
}
return null;
}
public boolean release(T df)
{
synchronized (pool) {
return pool.add(df);
}
}
public int getSize() {
synchronized (pool) {
return pool.size();
}
}
}
 
D

Danno

Now, is what do you mean by pool? This looks like a collection. When
I think of pool, I think of threading....
 
C

Chris Uppal

R said:
So my question is how can I instatiate a generic class?

You can't in any straightforward way.

One of the easiest approaches (assuming that you have need of a generic pool in
the first place -- which I rather doubt, though it may be true), is to make the
generic version abstract, and require concrete subclasses to provide an
implementation of the internal factory method. E.g. (just sketch code)

abstract class Pool<T>
` {
List<T> elements = new LinkedList<T>();

Pool()
{
this(initialSize());
}

Pool(int size)
{
for (int = 0; i < size; i++)
elements.add(makeElement());
}

protected abstract T makeElement();
protected int initialSize() { return 5; }

// etc...
}

Then programmers would create a Pool of Wdgets by subclassing:

class WidgetPool
extends Pool<Widget>
{
protected Widget makeElement()
{
return new Widget();
}

// Widgets are cheap, make the pool big by default
protected int initialSize() { return 5000; }
}

If you see what I mean. Note that you can also use subclassing to extend the
semantics of the pool, as in my simple example of changing the default size.
For instance, it might be worth adding hooks where the subclass can take
specific actions as an element is taken out of or added back to the pool (to
refresh it / quiesce it, perhaps). But beware of over-engineering too...

-- chris
 
R

R

Hi Chris,

I've written something like this (some parts are simplified i.e. try
catch block in constructor):

class GenericPool <T> {
public static final int POOL_MAX_SIZE = 5;
private List<T> pool;

public GenericPool(String name)
{
pool = new ArrayList<T>(GenericPool.POOL_MAX_SIZE);
Class cl = null;
try {
cl = Class.forName(name, true, ClassLoader.getSystemClassLoader());
for (int i = 0; i < GenericPool.POOL_MAX_SIZE; i++) {
@SuppressWarnings("unchecked")
T newInstance = (T)cl.newInstance();
pool.add(newInstance);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public T get()
{
synchronized (pool) {
if (!pool.isEmpty()) {
return pool.remove(pool.size() - 1);
}
}
return null;
}
public boolean release(T df)
{
synchronized (pool) {
return pool.add(df);
}
}
public int getSize() {
synchronized (pool) {
return pool.size();
}
}
}

to instantiate this Pool:

GenericPool<DAOFactory> Pool = new
GenericPool<DAOFactory>("mypackages.testing.DAOFactory");

but I agree it's too over-engineered ;)

best regards
R
 
T

Thomas Hawtin

R said:
T newInstance = (T)cl.newInstance();

I would avoid Class.newInstance. It passes exceptions from the
constructor straight through, even those it does not declare itself. So
checked exceptions become unchecked. If you stick to the long route via
java.lang.reflect.Constructor, then you should stay safe and obvious.

Tom Hawtin
 
C

Chris Uppal

R said:
cl = Class.forName(name, true, ClassLoader.getSystemClassLoader()); [...]
but I agree it's too over-engineered ;)

;-) It is a little...

Also, by hardwiring the choice of classloader you are making it unusable for
classes which should be loaded by custom classloaders. That might not matter
at all for your application, but many application frameworks (Servelet
containers and the like) load all application classes via custom classloaders,
so you might find yourself in trouble. I would recommend against using
reflection at all (for this), but at minimum you should change it to read just
cl = Class.forName(name);
in which case the classloader that loaded your Pool class will be used -- which
is, at least, less likely to be wrong.

If you /must/ go this route (either out of need, or out of stubbornness ;-)
then you should have the code that creates the Pool pass the class object
itself, rather than the class's name, to the constructor.

public class Pool<T>
{
public
Pool(Class<T> cl)
{
...

(Incidentally, there's nothing to be gained by naming the thing "GenericPool",
it /is/ generic, so there's no need to reiterate that in the name. You don't
see Java's standard Collection classes with names like
java.util.GenericList<T>...)

Alternatively, you could create a helper interface which defines a factory
object that the pool will use:

public interface
PoolEntryFactory<T>
{
T create(); // NB: no checked exceptions allowed !
}

public class Pool<T>
{
public
Pool(PoolEntryFactory<T> factory)
{
for (i = 0; i < 10; i++)
pool.add(factory.create());
...

But I think you'll agree that this is getting to be more bother than it's
worth.

-- chris
 
R

R

to tell the truth I haven't thought of thrown exceptions.
good point!

but I'm new to Java and I'm missing something
class Class has get(Declared)Constructor(Class[] args) method
but default constructor doesn't have any parameters - I tried to pass
null and 'new Class[] {}' as parameter but I couldn't get this
constructor.
In both situations I caught NoSuchMethodException:

Exception in thread "main" java.lang.NoSuchMethodException:
mypackages.testing.DAOFactory.<init>()

Method class has invoke method, but I haven't seen any
create/make/instantiate method in Constructor class.

Can you give a simple example of instantiating object from Constructor
class?

thanks in advance
best regards
R
 

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

Similar Threads

generics puzzle 57
thread pool with CachedThreadPool 8
Generics Issue 13
Generics 24
Tree design with generics 2
[Java Generics] T.class from <T> 2
generics + new = problem 4
Generics annoyance 18

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top