I know that similar problems have been discussed in several threads below, but I still cannot find a solution to my problem.
Other Topics: Compilers Behave Differently with a Generic Method Zero Parameter
Compiling Java generation code in eclipse but not on the command line
So, I wrote an event mechanism using events handler common to events and interfaces. I had code for logging events that generate an error on the javac command line, but not with the eclipse indigo. In the code below, EventRegistry simply captures the name of the event class and event handler in a string format.
I created the following interfaces
public interface Event{} public interface EventHandler<T extends Event> {}
Methods in the EventManager class
public <T extends Event, P extends EventHandler<T>> void registerManagedHandler( EventRegistry er, ClassLoader cl ) throws ClassNotFoundException { ... Class<T> eventClass = (Class<T>) cl.loadClass(er.getEventClass()); Class<P> eventHandlerClass = (Class<P>) cl.loadClass(er.getEventHandlerClass()); ... register(eventHandlerClass, eventClass); } private <T extends Event, P extends EventHandler<T>> void register( Class<P> handler, Class<T> eventClass ) { ... }
... in some other class. I have an expression.
EventManager.getInstance().registerManagedHandler(er,al);
Eclipse compiles code correctly, but an error occurs when compiling from javac on the command line
incompatible types; inferred type argument(s) com.mycompany.events.Event,java.lang.Object do not conform to bounds of type variable(s) T,P [javac] found : <T,P>void [javac] required: void [javac] EventManager.getInstance().registerManagedHandler(er,al);
There are similar methods for unregistering/enabling/disabling events that generate the same error. From the above code, I tried to remove type constraints ( <T extends Event, P extends EventHandler<T>> ) from registerManagedHandler, but then register (...) the method caused by the generated error
my modified registeredManagedHandler () ..
public void registerManagedHandler( EventRegistry er, ClassLoader cl ) throws ClassNotFoundException { ... Class<? extends Event> eventClass = (Class<? extends Event>) cl.loadClass(er.getEventClass()); Class<? extends EventHandler<? extends Event>> eventHandlerClass = (Class<? extends EventHandler<? extends Event>>) cl.loadClass(er.getEventHandlerClass()); ... register(eventHandlerClass, eventClass); }
New generated compilation time Error in eclipse too.
Bound mismatch: The generic method register(Class<P>, Class<T>) of type EventManager is not applicable for the arguments (Class<capture
I do not intend to remove type checks from the register (...) method.
Please let me know if more details about the code are required for understanding.
Please tell me the correct way to solve such problems or workarounds. I am new to generics, but before implementing this, I read the basic guides.
Also, I could not find a way to force eclipse to use sun-javac6 installed on my Ubuntu system instead of my own compiler. Although I know how to change the JRE in eclipse (Project -> Properties -> Java Build Path -> Libraries)
Thanks in advance.
Update: Thank you guys for your answers. Tell me if I can provide more information. My version of Eclipse is Indigo (3.7)
Here sscce. If you run the program in eclipse, it works fine (compilation and execution). But when you start it using the command line: i.e. Javac GenericTester.java, the following error appears. I confirmed this with the sscce.org compilation tool.
interface Event { } interface EventHandler<T extends Event> { } class EventRegistry { public String eventClass; public String eventHandlerClass; } class EventManager { public <T extends Event, P extends EventHandler<T>> void registerEvent( Class<T> eventClass, Class<P> eventHandlerClass) { } public <T extends Event, P extends EventHandler<T>> void registerEvent( EventRegistry er) throws ClassNotFoundException { Class<T> eventClass = (Class<T>) this.getClass() .getClassLoader().loadClass(er.eventClass); Class<P> eventHandlerClass = (Class<P>) this .getClass().getClassLoader() .loadClass(er.eventHandlerClass); registerEvent(eventClass, eventHandlerClass); } } class MyEvent implements Event { } class MyEventHandler implements EventHandler<MyEvent> { } public class GenericTester { public static void main(String[] args) { EventRegistry er = new EventRegistry(); er.eventClass = MyEvent.class.getName(); er.eventHandlerClass = MyEventHandler.class.getName(); try { new EventManager().registerEvent(er); System.out.println("It worked."); } catch (ClassNotFoundException e) {
An error from the command line, including the command I run:
nitiraj@pandora :~/mywork/GenericTest/src$ javac GenericTester.java GenericTester.java:40: incompatible types; inferred type argument(s) Event,java.lang.Object do not conform to bounds of type variable(s) T,P found : <T,P>void required: void new EventManager().registerEvent(er); ^ Note: GenericTester.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error
Additional information about java that I installed.
nitiraj@pandora :~/mywork/GenericTest/src$ java -version java version "1.6.0_30" Java(TM) SE Runtime Environment (build 1.6.0_30-b12) Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode) nitiraj@pandora :~/mywork/GenericTest/src$ javac -version javac 1.6.0_30