我知道類似的問題已經討論了幾個線程,但我仍然無法找到解決我的問題。Java泛型編譯在eclipse中,而不是從命令行
其他線程: Compilers behave differently with a null parameter of a generic method
Java generics code compiles in eclipse but not in command line
所以我在寫使用事件和事件處理程序接口仿製藥的事件機制。我有以下代碼註冊在命令行javac中產生錯誤的事件,但沒有使用eclipse indigo。在下面的代碼中,EventRegistry
只是以字符串格式捕獲事件和事件處理程序的類名。
我創建了以下接口
public interface Event{}
public interface EventHandler<T extends Event> {}
方法在我eventmanager進行類
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)
{
...
}
...在其它的類。我有一個聲明。
EventManager.getInstance().registerManagedHandler(er,al);
的Eclipse正確編譯的代碼,但在從上javac的命令行編譯
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);
存在用於unregistering/enabling/disabling
產生相同的錯誤事件類似的方法所產生的誤差。 從上面的代碼我試圖除去registerManagedHandler類型約束(<T extends Event, P extends EventHandler<T>>)
但然後註冊(...)方法調用產生的錯誤
我的改性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);
}
新生成的編譯時間錯誤也是日食。
Bound mismatch: The generic method register(Class<P>, Class<T>) of type EventManager is not applicable for the arguments
(Class<capture#20-of ? extends EventHandler<? extends Event>>, Class<capture#22-of ? extends Event>). The inferred type
capture#20-of ? extends EventHandler<? extends Event> is not a valid substitute for the bounded parameter <P extends
EventHandler<T>>
我不打算從register(...)方法中刪除類型檢查。
如果需要了解更多代碼細節,請告知我。
請告訴我處理此類問題或解決方法的正確方法。我對泛型非常陌生,但在實現此功能之前,我閱讀了基本指南。
另外我找不到任何方法強迫eclipse使用安裝在我的Ubuntu系統上的sun-javac6而不是它自己的編譯器。雖然我知道如何更改eclipse中的JRE(項目 - >屬性 - > Java構建路徑 - >庫)
在此先感謝。
更新:謝謝你們的迴應。告訴我是否可以提供更多信息。我的Eclipse版本是Indigo(3.7)
這是sscce。如果你在eclipse中運行該程序,它可以正常工作(編譯和執行)。但是當你用命令行運行它時:即javac GenericTester.java,則會出現以下錯誤。我已經用sscce.org的編譯器工具證實了這一點。從命令行
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
錯誤,包括我運行命令:
[email protected]:~/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
約我已經安裝了Java的一些詳細信息。
[email protected]:~/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)
[email protected]:~/mywork/GenericTest/src$ javac -version
javac 1.6.0_30
爲了更好地幫助越早,張貼[SSCCE](http://sscce.org/)。鑑於第一'?'是低於你的帖子提示我問..是你的問題「爲什麼SDK和Eclipse編譯器之間的行爲差異?」。如果是這樣,那麼我建議你添加,作爲編輯,讓你的問題..一個問題。 – 2012-03-25 11:38:43
@Nitraj您確定在命令行中使用的JDK與Eclipse用於編譯的相同嗎?你可以在你的問題中添加你正在使用的命令行嗎? – 2012-03-25 12:24:23
爲了重現您的編譯錯誤,瀏覽5個代碼片段中的不完整源代碼傳播非常困難。如果您希望我們幫助您,請發佈SSCCE。提示:如果你使用默認可見性(即非公開)聲明你的類型,它們都可以進入相同的源文件,這使得將代碼導入eclipse變得更容易。 – meriton 2012-03-25 13:25:50