簡體   English   中英

為什么你的 switch 語句數據類型不能很長,Java?

[英]Why can't your switch statement data type be long, Java?

以下是Sun 的 Java 教程的摘錄:

開關適用於byteshortcharint原始數據類型。 它還適用於枚舉類型(在類和繼承中討論)和一些“包裝”某些原始類型的特殊類: CharacterByteShortInteger (在簡單數據對象中討論)。

不允許long原始數據類型必須有充分的理由。 有人知道這是什么嗎?

我認為在某種程度上,它可能是基於典型切換使用的任意決定。

交換機基本上可以通過兩種方式實現(或者原則上是組合):對於少數情況,或者其值大范圍分散的情況,交換機基本上等同於臨時變量上的一系列ifs(打開的值必須只評估一次)。 對於或多或少連續值的中等數量的情況,使用切換表(Java中的TABLESWITCH指令),從而有效地在表中查找要跳轉到的位置。

這些方法中的任何一個原則上都可以使用長值而不是整數。 但是我認為將指令集和編譯器的復雜性與實際需求進行平衡可能只是一個實際的決定:你真正需要切換很長時間的情況很少見,因此必須重新編寫為一系列的IF語句,或以其他方式工作(如果有問題的長值靠得很近,你可以在你的Java代碼中切換int減去最低值的結果)。

因為他們沒有在字節碼中實現必要的指令,你真的不想寫那么多的情況,無論你的代碼如何“生產就緒”......

[編輯:摘自對此答案的評論,並在背景上添加一些內容]

確切地說,2,32是很多情況下,任何方法都有足夠長的時間來容納更多的東西,這將是非常可怕的! 用任何語言。 (我知道的任何語言的任何代碼最長功能略微超過6K SLOC -是的,這是一個很大的switch -這是真的無法控制。)如果你真的堅持與具有正long ,你應該只有一個int或者更少,那么你有兩個真正的選擇。

  1. 在散列函數的主題上使用一些變體將long壓縮為int 最簡單的一個,只有當你輸入錯誤時才使用,就是施展! 更有用的是這樣做:

     (int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF)) 

    在打開結果之前。 你必須弄清楚如何改變你正在測試的案例。 但實際上,這仍然很可怕,因為它沒有解決許多案件的真正問題。

  2. 如果您正在處理大量案例,那么更好的解決方案是將您的設計更改為使用Map<Long,Runnable>或類似的東西,以便您查找如何分派特定值。 這允許您將案例分成多個文件,這在案例數量變大時更容易管理,盡管組織所涉及的實現類主機的注冊變得更加復雜(注釋可能有助於您自動構建注冊碼)。

    FWIW,我多年前做過這個(我們在項目中轉換到新發布的J2SE 1.2部分)來構建用於模擬大規模並行硬件的自定義字節碼引擎(不,重復使用JVM因為從根本上不合適)所涉及的不同的值和執行模型)並且它極大地簡化了代碼的C版本所使用的大型switch的代碼。

要重申帶回家的消息,想要switch一個long消息表明你的程序中的類型錯誤,或者你正在構建一個涉及你應該使用類的那么多變化的系統。 在任何一種情況下重新考慮的時間。

因為查找表索引必須是32位。

我碰巧遇到了這個 12 歲的問題,我可以為這個問題提供最好的解決方案之一,即使用最新的 jdk,因為 long 和 Long 現在在 switch-case 語句中得到支持。 :)

長的32位體系結構由兩個單詞表示 現在,想象一下如果由於同步不足會發生什么情況,switch語句的執行會觀察到一次寫入時高32位,另一次寫入低32位! 它可以嘗試去....誰知道在哪里! 基本上是隨意的某個地方。 即使兩個寫入代表switch語句的有效情況,它們的有趣組合也可能既不會導致第一個也不會導致第二個 - 或者更糟糕的是,它可能導致另一個有效但無關的情況!

至少對於一個int(或更小的類型),無論你多么糟糕,switch語句至少會讀取某人實際編寫的值,而不是“憑空”的值。

當然,我不知道實際的原因(已經超過15年,我沒有注意那么久!),但是如果你意識到這樣一個結構可能是多么不安全和不可預測,你會同意的這是一個絕對非常好的理由永遠不會切換多頭(並且由於長打算 - 將會有32位機器,這個原因仍然有效)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM