[java] 왜 당신의 switch 문 데이터 유형이 길지 않습니까, Java?

다음은 Sun의 Java 자습서 에서 발췌 한 것입니다 .

스위치는 작동 byte, short, char, 및 int기본 데이터 형. 또한 특정 기본 유형을 “포장”고 (클래스와 상속에서 논의) 열거 유형과 몇 가지 특별한 클래스와 함께 작동 : Character, Byte, Short,과 Integer(단순 데이터 개체에서 논의).

long기본 데이터 유형이 허용되지 않는 이유가 있어야합니다 . 누구든지 그것이 무엇인지 압니까?



답변

일반적인 스위치 사용을 기반으로 한 임의의 결정이라고 생각합니다.

스위치는 기본적으로 두 가지 방법 (또는 원칙적으로 조합)으로 구현 될 수 있습니다. 소수의 경우 또는 값이 광범위하게 분산 된 경우 스위치는 기본적으로 임시 변수에 대한 일련의 if와 동일합니다. 켜진 값은 한 번만 평가해야합니다). 값이 다소 연속적인 적당한 수의 경우에는 스위치 테이블 (Java의 TABLESWITCH 명령어)이 사용되어 점프 할 위치가 테이블에서 효과적으로 조회됩니다.

이 방법 중 하나는 원칙적으로 정수가 아닌 긴 값을 사용할 수 있습니다. 하지만 명령 세트와 컴파일러의 복잡성과 실제 요구 사이의 균형을 맞추는 것은 아마도 실용적인 결정이라고 생각합니다. 실제로 긴 시간을 전환해야하는 경우는 드물기 때문에 A로 다시 작성해야합니다. 일련의 IF 문을 사용하거나 다른 방식으로 작업합니다 (문제의 긴 값이 서로 가깝다면 Java 코드에서 가장 낮은 값을 뺀 int 결과로 전환 할 수 있습니다).


답변

그들은 바이트 코드에서 필요한 지침을 구현하지 않았고 당신 때문에 정말 많은 경우, “제작 준비”코드가 얼마나 상관없이 쓰고 싶지 않아 …

[편집 :이 답변에 대한 의견에서 추출, 배경에 대한 추가 사항 포함]

정확히 말하면, 2³²는 많은 경우이며 그 이상을 저장할 수있는 방법을 가진 프로그램은 완전히 끔찍할 것입니다! 모든 언어로. (어떤 언어의 어떤 코드에서든 내가 아는 가장 긴 함수는 6k SLOC를 약간 넘는 것입니다. 예, 그것은 크며 switch정말 관리하기 어렵습니다.) 만약 당신이 하나 이하 long만 가져야 하는 곳에 집착한다면 int, 두 가지 실제 대안이 있습니다.

  1. 해시 함수 테마에 대한 몇 가지 변형을 사용 long하여 int. 가장 간단한 방법은 유형이 잘못되었을 때만 사용하는 것입니다. 더 유용한 방법은 다음과 같습니다.

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

    결과를 켜기 전에. 테스트 대상 케이스를 변환하는 방법도 알아 내야합니다. 그러나 실제로는 많은 경우의 실제 문제를 다루지 않기 때문에 여전히 끔찍합니다.

  2. 매우 많은 수의 케이스로 작업하는 경우 훨씬 더 나은 솔루션 Map<Long,Runnable>은 특정 값을 전달하는 방법을 찾을 수 있도록 a 또는 유사한 것을 사용하도록 설계를 변경하는 것입니다. 이를 통해 케이스를 여러 파일로 분리 할 수 ​​있습니다. 이는 케이스 수가 커지면 관리하기가 훨씬 더 쉽습니다.하지만 관련된 구현 클래스의 호스트 등록을 구성하는 것이 더 복잡해집니다 (주석은 다음을 허용함으로써 도움이 될 수 있습니다. 자동으로 등록 코드 작성).

    FWIW, 저는 수년 전에 대규모 병렬 하드웨어를 시뮬레이션하기위한 커스텀 바이트 코드 엔진을 구축 할 때 (프로젝트를 통해 새로 출시 된 J2SE 1.2로 전환했습니다)이 작업을 수행했습니다 (아니요, JVM 재사용은 근본적으로 다른 값과 실행 모델이 포함되어 있음) switchC 버전의 코드가 사용 하는 큰 코드에 비해 코드가 엄청나게 단순화 되었습니다.

하고 싶은, 테이크 가정 메시지를 반복하려면 switchA가에 long하나 당신이 당신의 프로그램 또는 당신이 클래스를 사용하는 것을 포함하는 많은 변화가있는 시스템을 구축하고 그 유형이 잘못 가지고 있다는 표시입니다. 두 경우 모두 재고 할 시간입니다.


답변

조회 테이블 인덱스는 32 비트 여야하기 때문입니다.


답변

32 비트 아키텍처에서 long은 두 단어로 표시됩니다 . 이제 불충분 한 동기화로 인해 switch 문을 실행하면 한 쓰기에서 높은 32 비트가, 다른 쓰기에서 32 비트가 낮은 long을 관찰 할 수 있습니다. …. 어디를 아는 사람에게 가려고 할 수 있습니다! 기본적으로 어딘가에 무작위로. 두 쓰기가 모두 switch 문에 대해 유효한 경우를 나타내더라도, 그들의 재미있는 조합은 아마도 첫 번째도 두 번째로도 이어지지 않을 것입니다. 또는 극도로 더 나쁘면 다른 유효하지만 관련없는 경우로 이어질 수 있습니다!

적어도 int (또는 그보다 작은 유형)를 사용하면 아무리 심하게 엉망이 되더라도 switch 문은 적어도 “공기에서 벗어난”값 대신 누군가가 실제로 쓴 값을 읽습니다 .

물론 실제 이유는 모르겠지만 (15 년이 넘었고 그렇게 오랫동안주의를 기울이지 않았습니다!) 그러한 구조가 얼마나 안전하지 않고 예측할 수 없는지 알고 있다면 동의 할 것입니다. 이것은 확실히 아주 좋은 이유 하지에 지금까지 정수 (Long) 스위치 (그리고 한 -pun intended-이 32 비트 시스템 일 것입니다,이 이유는 유효합니다)가 있습니다.


답변