2008-09-17 5 views
9

바이트 또는 짧은 형식의 변수를 선언하고 이들에 대해 산술 연산을 수행하려고하면 "형식이 일치하지 않습니다. 변환 할 수 없습니다. int to short "(또는 그에 상응하여"유형 불일치 : int를 바이트로 변환 할 수 없습니다 ").Java : "형식 불일치 : 정수를 바이트로 변환 할 수 없습니다"

byte a = 23; 
byte b = 34; 
byte c = a + b;

이 예제에서 컴파일 오류는 세 번째 줄에 있습니다.

+1

IIRC JVM은 바이트와 단락을 int로 저장하므로 일반적으로이 두 데이터 유형을 사용하면 거의 이점이 없습니다. 물론, 저는 여러분이 여러분의 예보다 훨씬 복잡한 것을하고 있으며, 아마도 아주 좋은 이유가 있음을 알고 있습니다. –

답변

8

Java 언어 사양 (5.6.2 이진 숫자 승격)에 따라 산술 연산자가 모든 숫자 유형에서 작동하도록 정의되었지만 byte 및 short 유형의 피연산자는 연산자에 전달되기 전에 int로 자동 승격됩니다.

byte 또는 short 형식의 변수에 대해 산술 연산을 수행하려면 식을 괄호로 묶고 (그 내부에서는 int 형식으로 연산이 수행됩니다.) 결과를 원하는 형식으로 다시 캐스팅해야합니다.

byte a = 23; 
byte b = 34; 
byte c = (byte) (a + b);

다음은 실제 Java 전문가의 질문입니다. 그 이유는 무엇입니까? byte 형과 short 형은 완벽하게 정밀한 수치 형입니다. Java가 이러한 유형의 직접 산술 연산을 허용하지 않는 이유는 무엇입니까? (처음에는 int로 변환 할 명백한 이유가 없으므로 대답은 "정확도 상실"이 아닙니다.)

업데이트 : jrudolph는이 동작이 JVM에서 사용할 수있는 작업, 전체 및 이중어 연산자 만 구현됩니다. 따라서 바이트와 단락의 연산자는 int로 변환해야합니다.

+0

성능 때문인 것 같네요. 일부 CPU에서는 CPU 레지스터보다 작은 피연산자를 사용하는 것이 더 비쌉니다. 아마 그것도 메모리에 정렬 유지하기 위해 바이트와 짧은 저장하는 32 비트 정수를 사용했습니다. – jassuncao

+0

내가 발견했기 때문에 - 작업은 CPU 레지스터에서 수행되지만 예 32 비트로 정렬됩니다. char에 대해 + 연산자를 수행 할 수 없습니다. – bestsss

5

당신의 후속 질문에 대한 답은 여기에 있습니다 : 유형 바이트 및 단기의

피연산자가 자동으로 사업자

그래서 물려되기 전에 int로 승진, 귀하의 예제에서, ab은 모두 + 연산자로 전달되기 전에 int으로 변환됩니다. 두 개의 int을 함께 추가 한 결과는 int입니다. 그 다음에 intbyte 값에 할당하려고 시도하면 정밀도가 저하 될 수 있기 때문에 오류가 발생합니다. 명시 적으로 결과를 캐스팅하면 컴파일러에게 "내가하는 일을 안다"라고 말합니다.

2

저는 JVM이 워드 크기와 더블 워드 크기의 두 가지 유형의 스택 값만 지원한다고 생각합니다.

그러면 스택에있는 워드 크기의 정수에서 작동하는 하나의 연산 만 필요하다고 결정했을 것입니다. 따라서 바이트 코드 수준에서는 iadd, imul 등이 있습니다 (바이트와 단락의 연산자가 없습니다).

이러한 연산의 결과로 int 값을 얻습니다. Java는 안전하게 작은 바이트 및 짧은 데이터 유형으로 다시 변환 할 수 없습니다. 그래서 그들은 바이트/짧은 값으로 값을 줄이기 위해 캐스트하도록합니다.

하지만 결국 당신이 맞습니다 :이 동작은 int의 동작과 일치하지 않습니다. 결과가 오버플로되면 문제없이 두 개의 int를 추가하고 오류를 얻을 수 있습니다.

1

Java 언어는 항상 산술 연산자의 인수를 int, long, float 또는 double로 승격합니다.따라서 다음 식을 사용하십시오.

a + b 

여기서 a와 b는 byte 유형입니다. 다음의 약식입니다.

(int)a + (int)b 

이 표현식은 int 유형입니다. 바이트 변수에 int 값을 할당 할 때 오류가 발생하는 것이 분명합니다.

왜 이런 식으로 언어를 정의합니까? a가 60이고 b가 70이라고 가정하면 a + b는 -126 - 정수 오버플로입니다. int가 될 것으로 예상되는 좀 더 복잡한 표현의 일부로, 이것은 어려운 버그가 될 수 있습니다. 배열 스토리지에 대한 바이트 및 단락의 사용, 파일 형식/네트워크 프로토콜 및 퍼즐 러에 대한 상수 사용을 제한합니다.

JavaPolis 2007에서 흥미로운 기록이 있습니다. James Gosling은 부호없는 산술 연산이 얼마나 복잡한 지 (그리고 Java에없는 이유)에 대한 예제를 제공합니다. Josh Bloch는 그의 예제가 일반적인 부호있는 산술에서도 잘못된 예를 제시한다고 지적합니다. 이해할 수있는 산술을 위해서는 임의 정밀도가 필요합니다.

관련 문제