I could need some help with a problem I have with Java's generics. I constructed a little example for to show what I mean.
Handler
package generalizingTest;
public class Handler<S extends Server<?>> {
public S server;
public Handler(S server) {
this.server = server;
}
}
SubHandler
package generalizingTest;
public class SubHandler<S extends Server<?>> extends Handler<S> {
public SubHandler(S server) {
super(server);
}
public void subHandlerMethod() {
}
}
Server
package generalizingTest;
import java.util.ArrayList;
public class Server<H extends Handler<?>> {
public ArrayList<H> handlers;
public Server() {
handlers = new ArrayList<H>();
}
public void addHandler(H c) {
handlers.add(c);
}
}
SubServer
package generalizingTest;
public class SubServer<H extends Handler<?>> extends Server<H> {
public void subServerMethod() {
}
}

Startup
package generalizingTest;
public class Startup {
public static void main(String[] args) {
Server<Handler<?>> serverWHandler = new Server<Handler<?>>();
Server<SubHandler<?>> serverWSubHandler = new Server<SubHandler<?>>();
SubServer<Handler<?>> subServerWHandler = new SubServer<Handler<?>>();
SubServer<SubHandler<?>> subServerWSubHandler = new SubServer<SubHandler<?>>();
Handler<Server<?>> handlerWServer = new Handler<Server<?>>(serverWHandler);
Handler<SubServer<?>> handlerWSubServer = new Handler<SubServer<?>>(subServerWHandler);
SubHandler<Server<?>> subHandlerWServer = new SubHandler<Server<?>>(serverWSubHandler);
SubHandler<SubServer<?>> subHandlerWSubServer = new SubHandler<SubServer<?>>(subServerWSubHandler);
serverWHandler.addHandler(handlerWServer);
subServerWHandler.addHandler(handlerWSubServer);
serverWSubHandler.addHandler(subHandlerWServer);
subServerWSubHandler.addHandler(subHandlerWSubServer);
subServerWHandler.subServerMethod();
subServerWSubHandler.subServerMethod();
handlerWSubServer.server.subServerMethod();
subHandlerWSubServer.server.subServerMethod();
subHandlerWServer.subHandlerMethod();
subHandlerWSubServer.subHandlerMethod();
System.out.println(subHandlerWSubServer.server.handlers.get(0).getClass().getName()); // SubHandler
//produces an error:
/*
* Unresolved compilation problem:
* The method subHandlerMethod() is undefined for the type Handler<capture#9-of ?>
*/
//subHandlerWSubServer.server.handlers.get(0).subHandlerMethod();
}
}
I just started learning about generics. They seem to be efficient but I am not sure if I solved the problem of the generics loop () correctly with the wildcard and why those errors occur.
I really hope someone can help me out.
EDIT:
So it seems like I did not highlighted the initial problem enough. The following should be possible in any depth:
subHandlerWSubServer.server.handlers.get(0).server.handlers.get(0).server.handlers.get(0). ... .server.handlers.get(0).subHandlerMethod();
EDIT:
So this problem seems not to be solvable due to an endless loop of definition or the missing self value, see Siguza’s anwser.
Here is the discussion between Siguza, user889742 and myself about this topic.
If I understood you correctly, if you have a Handler<S> you want all handlers on that server to be of type Handler<S>, right?
For that, S.add() would have to only accept objects of type Handler<S>. But in order to implement that in the base class Server, you would need S, so that:
public class Server<H>
{
public ArrayList<H<S>> handlers;
public Server()
{
handlers = new ArrayList<H<S>>();
}
public void addHandler(H<S> c)
{
handlers.add(c);
}
}
The only problem with this is that S is not defined, and you cannot easily define it. What you would need is something that, in the context of Server, means Server, and in the context of SubServer, means SubServer. Basically this.getClass(), but as a compile-time type expression. If Java had a keyword for that, say self, you could use it like this:
public class Server<H>
{
public ArrayList<H<self>> handlers;
public Server()
{
handlers = new ArrayList<H<self>>();
}
public void addHandler(H<self> c)
{
handlers.add(c);
}
}
Then Server.add() would take Handler<Server>, and SubServer.add() would take Handler<SubServer>.
Sadly, Java has no such thing, therefore what you're trying to do is not possible this way.
Java does many things well.
Generics aren't one of them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With