왜 "int i = 2147483647 + 1;" 그러나“바이트 b = 127 + 1;” 컴파일 할 수 없습니까?


126

int i = 2147483647 + 1;OK이지만 byte b = 127 + 1;컴파일 할 수 없습니까?


16
나는 정말로 의심을 가지고 있습니다 : 왜 byte데이터 유형이 그렇게 고통 스럽 습니까?!
BoltClock

9
byte서명이 아닌 서명 된 디자인 실수입니다 .
신뢰할 수없는

4
@BoltClock 올바르게 사용하는 방법을 모르면 고통입니다. stackoverflow.com/questions/397867/…
starblue

2
@starblue, Java 바이트 유형이 적용 가능한 실제 예가 있습니까?
Thorbjørn Ravn Andersen

바이트로 지정된 데이터가있는 경우 byte명확성을 위해 Java 를 사용하십시오 ( 예 : 매개 변수). 이 경우 int값을 할당 할 수 없다는 사실은 일부 버그를 잡을 수도 있습니다. 또는 byte배열로 공간을 절약 하는 데 사용하십시오 . byte바이트에 맞는 단일 값 에는 사용하지 않습니다 .
starblue

답변:


172

상수는 int로 평가되므로 2147483647 + 1오버플로가 발생하고 새로운 int를 제공합니다.이 속성은으로 지정할 수 int있지만 127 + 1으로 int128으며에 할당 할 수 없습니다 byte.


10
실제로, 오늘 저는 그에 관한 퍼즐을 포함하여 Java 퍼즐 게임을 읽었 습니다. 여기를보십시오 : javapuzzlers.com/java-puzzlers-sampler.pdf- 퍼즐 3
MByD

3
문제는 int이진 숫자 승격으로 인한 유형 이며 값 127은 빨간색 청어입니다.
starblue

상수가 무한 정도로 평가되고 int i = 2147483647 + 1에서 오류가 발생하는 것을 선호합니다.
Eduardo

@MByD : " while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte." 라고 말했듯 이 이것은 50 + 1이 다음 byte과 같이 평가되어 할당 될 수 있음을 의미 byte합니까?
Bhushan

1
@ 10101010-정확하지 않습니다. 바이트에 할당 할 수 있지만 먼저 (표준에 따라) int로 평가됩니다.
MByD

35

리터럴 (127)은 int 유형의 값을 나타낸다. 리터럴 1도 마찬가지입니다.이 둘의 합은 정수 128입니다. 두 번째 경우 문제는 이것을 바이트 유형의 변수에 할당한다는 것입니다. 실제 표현식 값과는 아무런 관련이 없습니다. 강제 (*)를 지원하지 않는 Java와 관련이 있습니다. 타입 캐스트를 추가해야합니다

byte b = (byte)(127 + 1);

그런 다음 컴파일됩니다.

(*) 적어도 String-to-integer, float-to-Time 종류가 아닙니다. Java는 어떤 의미에서 손실이없는 경우 강제를 지원합니다 (Java는 이것을 "확장"이라고합니다).

그리고 "강제"라는 단어는 바로 잡을 필요가 없었습니다. 그것은 매우 신중하고 정확하게 선택되었습니다. 가장 가까운 소스에서 직접 (Wikipedia) : "대부분의 언어에서 강제 변환은 컴파일 또는 런타임 중에 암시 적 변환 을 나타내는 데 사용됩니다 ." 및 "컴퓨터 과학, 형식 변환, 타입 캐스팅 및 강압에있는 다른 다른에 하나 개의 데이터 유형의 엔티티를 변경 암묵적으로 또는 명시 적으로하는 방법은.".


코드 예제는 아마도 바이트 b = (바이트) 127 + 1이어야합니다. 예를 들어 '최대한 바이트 값에 1을 추가하십시오'는 예제에서 128의 int 값을 바이트 값으로 바꿉니다.
NKCSS

6
@NKCSS-당신이 옳지 않다고 생각합니다 .128 (byte)(127 + 1)(정수)를 바이트로 (byte)127 + 1캐스트하는 반면, 이것은 127을 바이트로 캐스트하지만 다시 int로 캐스팅합니다 .1 (int)에 추가되었으므로 128 (int)을 얻고 오류가 유지됩니다.
MByD

6

@MByD의 증거로 :

다음 코드는 컴파일됩니다.

byte c = (byte)(127 + 1);

expression (127 + 1)이 int이고 scope off byte유형을 벗어나 더라도 결과는로 캐스트됩니다 byte. 이 표현식은을 생성합니다 -128.


3

JLS3 # 5.2 할당 변환

(변수 = 표현식)

또한 표현식이 byte, short, char 또는 int 유형의 상수 표현식 (§15.28) 인 경우 :

변수의 유형이 바이트, 짧은 또는 문자이고 상수 표현식의 값이 변수의 유형으로 표현 가능한 경우 축소 기본 변환이 사용될 수 있습니다.


이 절이 없으면 글을 쓸 수 없습니다

byte x = 0;
char c = 0;

그러나 우리가 이것을 할 수 있을까요? 나는 그렇게 생각하지 않습니다. 프리미티브 사이의 변환에는 꽤 많은 마술이 진행되고 있으므로 매우 신중해야합니다. 나는 글을 쓰지 않을 것이다

byte x = (byte)0;

우리가 할 수 있어야하는 질문에 관해서는 ... 나는 정말로 잘못된 것을 보지 byte x = 0못했지만 다시 C 프로그래머입니다.
Grady Player

char c = 0에 대한 인수를 볼 수는 있지만 바이트 x = 0이 잘못된 이유는 무엇입니까?
Michael Burge

바이트 변수에 바이트 0을 할당한다고 생각하면 훈련되지 않은 눈으로 오도됩니다. 이 예제에서는 크게 해를 끼치지는 않지만 일반적으로 바이트 / 짧은 / 문자에서 작업하면 암시 적 변환으로 인해 매우 혼란 스러울 수 있습니다. 사람들이 생각하는 것보다 훨씬 더 복잡합니다. 내 코드에서 최대한 명확성을 원하고 몇 가지 주요 스트로크를 저장하기 위해 불확실성을 도입하지 마십시오.
평판 좋은

축소 기본 변환이 long에서 int까지 일 때 비슷한 규칙이 적용됩니까 (예 : int i = 1 + 0L)? 인용 된 텍스트가 명시 적으로 그 경우를 제외하기 때문에 묻습니다.
Erwin Smout

@Erwin 아니오, int i=0L불법입니다.
신뢰할 수없는
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.