對於我的Java遊戲服務器,我發送數據包的操作ID,它基本上告訴服務器數據包的用途。我想將每個Action ID(一個整數)映射到一個函數。有沒有辦法做到這一點,而不使用開關?Java中的函數指針/代表?
回答
這個怎麼樣? (如果您需要傳遞一些參數,請使用具有合適參數的函數定義您自己的接口,然後使用該參數代替Runnable)。
我認爲functionA和functonB被調用的開關會更清晰的代碼。這只是將ID映射到函數到您要加載映射的代碼段,而不是調用函數的位置。 – 2008-12-28 04:47:24
Java沒有一流的函數指針。爲了實現類似的功能,你必須定義和實現一個接口。你可以使用匿名內部類更容易,但它仍然不是很漂亮。這裏有一個例子:
public interface PacketProcessor
{
public void processPacket(Packet packet);
}
...
PacketProcessor doThing1 = new PacketProcessor()
{
public void processPacket(Packet packet)
{
// do thing 1
}
};
// etc.
// Now doThing1, doThing2 can be used like function pointers for a function taking a
// Packet and returning void
有關Java中的「函數指針」的更多信息,請參閱:http://stackoverflow.com/q/122407/545127 – Raedwald 2013-02-25 13:35:31
你有沒有使用Swing/AWT?他們的事件層次結構解決了類似的問題。圍繞Java的功能傳遞方式是一個接口,例如
public interface ActionHandler {
public void actionPerformed(ActionArgs e);
}
然後,如果你想整數映射到這些對象,你可以使用像一個java.util.HashMap<Integer,ActionHandler>
來管理。實際的實現可以使用匿名類(Java的「lambda」的最佳近似值),也可以放在適當的類中。這裏的匿名類方式:
HashMap<Integer,ActionHandler> handlers;
handlers.put(ACTION_FROB, new ActionHandler() {
public void actionPerformed(ActionArgs e) {
// Do stuff
// Note that any outer variables you intend to close over must be final.
}
});
handlers.get(ACTION_FROB).actionPerformed(foo);
(編輯)如果你想更加辱罵,你可以初始化HashMap中,像這樣:
HashMap<Integer,String> m = new HashMap<Integer,String>() {{
put(0,"hello");
put(1,"world");
}};
的Java並沒有真正有函數指針(我們取而代之的是匿名內部類)。但是,使用開關真的沒什麼問題,只要你打開價值而不是打開類型。有沒有理由不想使用交換機?看起來你需要在代碼中的某處執行Action ID和動作之間的映射,爲什麼不簡單呢?
您可以通過使用責任鏈模式來做到這一點。
這是一種將不同對象鏈接在一起的模式,如鏈接列表。即每個對象都有一個對鏈中下一個的引用。鏈中的對象通常處理一個特定的行爲。對象之間的流程與switch-case語句非常相似。
有一些問題,例如,它將您的邏輯分散開來,過長的鏈會導致性能問題。但是隨着這些問題的發生,您可以獲得更高的可測試性和更強的凝聚力。此外,您不限於將enum,byte,int short和char表達式用作分支的觸發器。
檢查閉包在lambdaj庫中它們是如何實現的。他們實際上有非常類似於C#委託行爲:
呀,但使用的接口意味着你必須創建,這意味着要通過它設置的每個函數每次回調的接口。創建一個委託類來處理這個問題給你(不是一個真正的函數指針),而是要傳遞的函數,如果你濫用通用類型作爲返回類型,那麼你不必將瓶頸下降到幾乎沒有。
c#委託(MultiCastDelegate是正確的)從使用方法MethodInfo獲取信息,這與使用java.lang.reflect.method的Delegate類需要做的事情是一樣的。我在本網站的另一種形式上發佈了代理(T)類的代碼,處理這個問題。我做它是因爲(是)來自C++我需要一個更好的方式來傳遞函數(尤其是Void),然後必須創建一個函數或更多的接口。現在我可以選擇填充參數信息的函數。 Voila`! JIT或JVM的速度沒有明顯的下降,很好用。如果我只有一個星期只學習java編程,任何java程序員都可以做到。
另外,它在創建基本偵聽器和基本接口以傳入偵聽器時效果很好。由於函數的名稱已更改,因此不必再編寫另一個偵聽器。創建委託類具有很大的優勢,因爲非常有用並且可以通過。
您可以接口靜態方法。該方法允許您指定參數。聲明你的界面...
public interface RouteHandler {
void handleRequest(HttpExchange t) throws IOException;
}
而且你的地圖...
private Map<String, RouteHandler> routes = new HashMap<>();
然後實現匹配接口/ PARAMS靜態方法......
public static void notFound(HttpExchange t) throws IOException {
String response = "Not Found";
t.sendResponseHeaders(404, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
可以再加入這些方法進入你的地圖...
routes.put("/foo", CoreRoutes::notFound);
,並按如下方式調用它們:
RouteHandler handler = routes.get("/foo");
handler.handleRequest(exchange);
- 1. 代表和函數指針
- 2. Java中的函數指針
- 3. 函數指針/函數表
- 4. 函數指針的指針值代表什麼?
- 5. Java中函數指針的陣列
- 6. python中函數指針的替代
- 7. 參數列表中的函數指針
- 8. C++中函數指針的指針
- 9. 函數指針指向一個函數指針的函數
- 10. c函數指針反函數指針
- 11. 在Swift中表示NULL函數指向C函數的指針
- 12. 指針?指針函數?
- 13. C中的函數指針表C
- 14. 指針,鏈表和函數
- 15. 鏈表和函數指針
- 16. iOS中的函數指針?
- 17. 函數中的雙指針
- 18. FSM中的函數指針
- 19. Fortran中的函數指針
- 20. JavaScript中的函數指針
- 21. void函數中的指針
- 22. 陣列的函數指針的指針
- 23. 指向結構函數指針的函數指針
- 24. 函數指針
- 25. 函數指針
- 26. 函數指針
- 27. 函數指針
- 28. 函數指針?
- 29. 函數指針
- 30. 函數指針
總體而言,交換機將會更好。 – TheSoftwareJedi 2008-12-28 12:44:38
是的,開關幾乎肯定會更快,更小,更乾淨。 – 2008-12-28 13:30:32
[Java中函數指針最接近的替代函數是什麼?](http://stackoverflow.com/questions/122407/whats-the-nearest-substitute-for-a-function-pointer-in-java) – Raedwald 2013-02-25 13:36:27