Advanced question about generics

V

Vincent Cantin

Hello,

I have a class Server<C extends Connection> that accepts some connections
are for each of them creates an instance of C.

Problem : the implementation of the class need to have C.class in order to
create its instance but it doesn't know it unless I ask the user of my class
to give it in parameter.

So the user of the class write something like that :

Server server = new Server<MyConnection>(MyConnection.class);

but I would like him to only write something like that :

Server server = new Server<MyConnection>();

Is there something in the language of Java 1.5 that can do implicitly what I
want ?

Thank you,
Vincent
 
X

xarax

Vincent Cantin said:
Hello,

I have a class Server<C extends Connection> that accepts some connections
are for each of them creates an instance of C.

Problem : the implementation of the class need to have C.class in order to
create its instance but it doesn't know it unless I ask the user of my class
to give it in parameter.

So the user of the class write something like that :

Server server = new Server<MyConnection>(MyConnection.class);

but I would like him to only write something like that :

Server server = new Server<MyConnection>();

Is there something in the language of Java 1.5 that can do implicitly what I
want ?

I believe there is nothing to do exactly what you
want as described.

However, you may want to consider passing a factory
object to the constructor. The factory object will
instantiate an object of the correct type. The factory
object should be declared generically (via an interface
type) so that the compiler can verify that it is delivering
the correct type.
 
M

Michael Borgwardt

Vincent said:
So the user of the class write something like that :

Server server = new Server<MyConnection>(MyConnection.class);

but I would like him to only write something like that :

Server server = new Server<MyConnection>();

Is there something in the language of Java 1.5 that can do implicitly what I
want ?

That's IMO not possible, because generics don't exist on the bytecode level,
they're purely for the sake of the compiler. That means what gets *executed*
in the end is:

Server server = new Server();

With to MyConnection added whenever a method of server is called that
requires them.
 
J

Jesper Nordenberg

Vincent Cantin said:
Hello,

I have a class Server<C extends Connection> that accepts some connections
are for each of them creates an instance of C.

Problem : the implementation of the class need to have C.class in order to
create its instance but it doesn't know it unless I ask the user of my class
to give it in parameter.

So the user of the class write something like that :

Server server = new Server<MyConnection>(MyConnection.class);

but I would like him to only write something like that :

Server server = new Server<MyConnection>();

Is there something in the language of Java 1.5 that can do implicitly what I
want ?

No, not possible because of type erasure. A flexible solution is to
pass a factory object that create the instances, for example:

Server server = new Server<MyConnection>(new Factory<MyConnection>() {
public MyConnection create() {
return new MyConnection();
}
});

public interface Factory<T> {
T create();
}

This has several advantages over directly calling a constructor using
reflection.

/Jesper Nordenberg
 
M

Michal Kleczek

Jesper said:
No, not possible because of type erasure. A flexible solution is to
pass a factory object that create the instances, for example:

Server server = new Server<MyConnection>(new Factory<MyConnection>() {
public MyConnection create() {
return new MyConnection();
}
});

public interface Factory<T> {
T create();
}

This has several advantages over directly calling a constructor using
reflection.

/Jesper Nordenberg
Hi,
actually it is the same as the original solution - but more verbose.
To avoid wiriting "MyConnection" twice you should use a static generic
method:

public class Server<T extends Connection> {

public static <S> Server<? extends S> create(Class<S> clazz) {
return new Server<S>(clazz);
}

public Server(Class<T> c) {
//...
}

}

Client code:

Server<MyConnection> s = Server.create(MyConnection.class);

Cheers,
Michal
 
A

Adam Jenkins

Michal Kleczek said:
Hi,
actually it is the same as the original solution - but more verbose.
To avoid wiriting "MyConnection" twice you should use a static generic
method: [snip]
Client code:

Server<MyConnection> s = Server.create(MyConnection.class);

I still count two "MyConnection"s in that statement, so I'm not sure
what you've gained.
 
J

Jesper Nordenberg

Michal Kleczek said:
Hi,
actually it is the same as the original solution - but more verbose.

No, it's not the same. The Factory solution is more flexible because
it allows you to use any constructor of the MyConnection class, or
even not to create a new object at all. For example:

final MyConnection connection = getConnection();

Server server = new Server<MyConnection>(new Factory<MyConnection>() {
public MyConnection create() {
return connection;
}
});


Server server2 = new Server<MyConnection>(new Factory<MyConnection>()
{
public MyConnection create() {
return new MyConnection("This is an argument!");
}
});

This is something you can't do by just passing the MyConnection.class
object.

/Jesper Nordenberg
 
M

Michal Kleczek

Jesper said:
No, it's not the same. The Factory solution is more flexible because
it allows you to use any constructor of the MyConnection class, or
even not to create a new object at all. For example:

final MyConnection connection = getConnection();

Server server = new Server<MyConnection>(new Factory<MyConnection>() {
public MyConnection create() {
return connection;
}
});


Server server2 = new Server<MyConnection>(new Factory<MyConnection>()
{
public MyConnection create() {
return new MyConnection("This is an argument!");
}
});

This is something you can't do by just passing the MyConnection.class
object.

/Jesper Nordenberg
Hi,
I agree with you it's more flexible, but has nothing to do with generics.
Michal
 
M

Michal Kleczek

Adam said:
Michal Kleczek said:
Hi,
actually it is the same as the original solution - but more verbose.
To avoid wiriting "MyConnection" twice you should use a static generic
method:
[snip]

Client code:

Server<MyConnection> s = Server.create(MyConnection.class);


I still count two "MyConnection"s in that statement, so I'm not sure
what you've gained.
Hi,
It's still better than three in this statement:

Server<MyConnection> s = new Server<MyConnection>(MyConnection.class>;

Michal
 

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
can this be done with generics? 32
Generics Amanuensis? 2
Question about my projects 3
Generics 24
Generics 12
Generics question 6
Generic generics help 7

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top