Java에서 두 문자를 추가 한 결과는 int 또는 char입니까?


81

추가 할 때 'a' + 'b'그것은 195은 출력 데이터 형이며, 생산 char또는 int?


3
유형이 있다면 char다음의 값이 'a' + 'b'되지 않을 것 195하지만'Ã'
Joren

1
여기에 195가 있습니다 -ideone.com 이지만 Eclipse에는 없습니다.
주황색

2
당신은 알고리즘 책에서 읽었습니다. 나는 정확히 때문에이 연습의 여기 온)
잭 트웨인에게

답변:


133

Java 문자, 단락 또는 바이트를 추가 한 결과는 int입니다 .

이진 숫자 프로모션에 대한 Java 언어 사양 :

  • 피연산자 중 하나라도 참조 유형이면 unboxing 변환 (§5.1.8)이 수행됩니다. 그때:
  • 피연산자가 double 유형이면 다른 피연산자가 double로 변환됩니다.
  • 그렇지 않으면 피연산자가 float 유형이면 다른 피연산자가 float로 변환됩니다.
  • 그렇지 않고 피연산자 중 하나가 long 유형이면 다른 피연산자가 long으로 변환됩니다.
  • 그렇지 않으면 두 피연산자가 모두 int 유형으로 변환됩니다.

그러나 복합 할당 연산자 (예 : + =)에 대한 내용에 유의하십시오 .

이진 연산의 결과는 왼쪽 변수 ...의 유형으로 변환되고 변환 결과는 변수에 저장됩니다.

예를 들면 :

char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK

일반적으로 결과의 유형을 찾을 수있는 한 가지 방법은이를 Object로 캐스트하고 어떤 클래스인지 물어 보는 것입니다.

System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer

성능에 관심이있는 경우 Java 바이트 코드 에는 더 작은 데이터 유형의 산술 전용 명령조차 없습니다. 예를 들어, 추가의 경우 iadd(int의 경우), ladd(longs의 경우), fadd(float의 경우), dadd(doubles의 경우) 명령어 가 있습니다. x += y더 작은 유형으로 시뮬레이션하기 위해 컴파일러는 ( "int to char") iadd와 같은 명령어를 사용하여 int의 상위 바이트를 사용 하고 0으로 i2c만듭니다. 네이티브 CPU에 1 바이트 또는 2 바이트 데이터에 대한 전용 명령이있는 경우 런타임에이를 최적화하는 것은 Java 가상 머신에 달려 있습니다.

문자를 숫자 유형으로 해석하지 않고 문자열로 연결하려는 경우 여러 가지 방법이 있습니다. 가장 쉬운 방법은 식에 빈 문자열을 추가하는 것입니다. 문자와 문자열을 추가하면 문자열이 생성되기 때문입니다. 이러한 모든 표현식의 결과는 String입니다 "ab".

  • 'a' + "" + 'b'
  • "" + 'a' + 'b'(이것은 "" + 'a'먼저 평가 되기 때문에 작동 합니다. ""이 대신 끝에 있으면 얻을 것입니다 "195")
  • new String(new char[] { 'a', 'b' })
  • new StringBuilder().append('a').append('b').toString()
  • String.format("%c%c", 'a', 'b')


7

에 대한 다음 표현을 배우고 싶을 수 있습니다 char.

char c='A';
int i=c+1;

System.out.println("i = "+i);

이것은 Java에서 완벽하게 유효하며 66의 문자 (유니 코드)의 해당 값인을 반환합니다 c+1.


String temp="";
temp+=c;
System.out.println("temp = "+temp);

이것은 Java에서 너무 유효하며 String 유형 변수는 temp자동으로 cchar 유형을 허용 temp=A하고 콘솔에서 생성 합니다.


다음 명령문은 모두 Java에서도 유효합니다!

Integer intType=new Integer(c);
System.out.println("intType = "+intType);

Double  doubleType=new Double(c);
System.out.println("doubleType = "+doubleType);

Float floatType=new Float(c);
System.out.println("floatType = "+floatType);

BigDecimal decimalType=new BigDecimal(c);
System.out.println("decimalType = "+decimalType);

Long longType=new Long(c);
System.out.println("longType = "+longType);

c은 유형 이지만 char각 생성자에서 오류없이 제공 될 수 있으며 위의 모든 문은 유효한 문으로 처리됩니다. 그들은 각각 다음과 같은 출력을 생성합니다.

intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65

char원시 숫자 정수 유형이므로 변환 및 승진을 포함하여 이러한 짐승의 모든 규칙의 적용을받습니다. 이에 대해 읽어보고 싶을 것이며 JLS는 이에 대한 최고의 소스 중 하나입니다 : 전환 및 프로모션 . 특히 "5.1.2 Widening Primitive Conversion"에 대한 짧은 내용을 읽어보십시오.


3

Java 컴파일러는이를 둘 중 하나로 해석 할 수 있습니다.

프로그램을 작성하고 컴파일러 오류를 찾아서 확인하십시오.

public static void main(String[] args) {
    int result1 = 'a' + 'b';
    char result2 = 'a' + 'b';
}

그것이 문자라면, 첫 번째 줄은 나에게 오류를 줄 것이고 두 번째 줄은 그렇지 않을 것입니다. int이면 반대가 발생합니다.

나는 그것을 컴파일하고 나는 ..... 오류가 없습니다. 따라서 Java는 둘 다 허용합니다.

그러나 인쇄했을 때 다음을 얻었습니다.

정수 : 195

문자 : Ã

당신이 할 때 일어나는 일은 다음과 같습니다.

char result2 = 'a' + 'b'

암시 적 변환이 수행됩니다 ( int 에서 char 로의 "기본 축소 변환" ).


두 번째 경우에는 축소로 인한 정밀도 손실 가능성에 대한 컴파일러 경고가 표시되지 않은 것에 놀랐습니다.
Hot Licks 2011

@eboix : 당신이 쓴 "컴파일러는 자동으로 하나 char 또는 INT에 캐스트" [원문] ... 때문에 정확하지 않은 어떤 INT는 에 "주조"되지 INT 와에서 진행 INT A와 문자가 호출되지 않습니다 "캐스트"이지만 "좁아지는 원시 변환"; )
TacticalCoder

네. 나도 그것을 기대하고 있었다. 나는 실제로 프로그램을 만들기 전에 그것에 대한 대답의 일부를 작성했지만 경고 나 오류가 없다는 것을 알았을 때 삭제했습니다.
eboix

@eboix : eh eh :) 나는 그것을 편집했을 것입니다. 그러나 나는 아직 2 000 개의 평판 포인트를 가지고 있지 않기 때문에, 편집 대신에 나의 코멘트; )
TacticalCoder

원하는 경우 @ user988052, 원래 상태로 다시 변경할 수 있으며 편집하여 포인트를 얻을 수 있습니다. 평판 포인트가 2000 점 미만인 경우에도 편집 할 수 있습니다. 유일한 것은 게시물을 작성한 사람이 편집을 수락해야한다는 것입니다. 나는 당신이 정당하게 당신의 두 가지 점을 얻을 수 있도록 그것을 지금 다시 바꿀 것입니다.
eboix 2011

1

바이너리 승격 규칙 에 따르면 피연산자가 double, float 또는 long이 아니면 둘 다 int로 승격됩니다. 그러나 나는 char 유형을 숫자로 취급하는 것에 대해 강력하게 조언합니다.


1
char숫자 값으로 사용 하는 것은 전적으로 그 목적에 부합하므로 JLS가 그러한 사용에 많은 말을 바칩니다.
Lew Bloch

1

이미 정답이 있지만 (JLS에서 참조 됨) 두 개의을 int추가 할 때 를 얻었는지 확인하는 약간의 코드가 있습니다 char.

public class CharAdditionTest
{
    public static void main(String args[])
    {
        char a = 'a';
        char b = 'b';

        Object obj = a + b;
        System.out.println(obj.getClass().getName());
    }
}

출력은

java.lang.Integer


권투 변환을 믹스에 던 졌기 때문에 이것은 설득력있는 검증이 아닙니다. 유형 intInteger동일한 것이 아닙니다. 보다 설득력있는 검증은 변수 또는 변수 에 할당 a + b을 시도 int하는 것 char입니다. 후자는 "당신이를 할당 할 수 없습니다 효과를 말한다 컴파일 오류가 있습니다 intA를을 char".
Stephen C

0

char로 표현 Unicode함으로써 값과 위치 유니 코드 값을 표현 \u하였다 Hexadecimal값.

char승격 된 값 에 대한 산술 연산으로 int결과 'a' + 'b'는 다음과 같이 계산됩니다.

1.) Unicode해당 값을 char사용하여 적용Unicode Table

2.) 16 진수를 10 진수로 변환 한 다음 Decimal값에 대한 연산을 수행 합니다.

    char        Unicode      Decimal
     a           0061          97
     b           0062          98  +
                              195

Unicode To Decimal Converter

0061

(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (1 * 16 0 )

(0 * 4096) + (0 * 256) + (6 * 16) + (1 * 1)

0 + 0 + 96 + 1 = 97

0062

(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (2 * 16 0 )

(0 * 4096) + (0 * 256) + (6 * 16) + (2 * 1)

0 + 0 + 96 + 2 = 98

그 후 97 + 98 = 195


예 2

char        Unicode      Decimal
 Ջ           054b         1355
 À           00c0          192 
                      --------
                          1547    +
                          1163    -
                             7    /
                        260160    *
                            11    %

이것은 질문이 요구하는 것이 아닙니다.
Stephen C

참고로, 위 댓글에 대한 자세한 답변은 삭제 된 게시물에서 내 답변이 마이그레이션 된 이유를 설명하는 모드에 의해 제거되었습니다. SO 중재의 결함을 은폐하기 위해 내 응답이 삭제 된 경우 적어도 위의 댓글을 제거하거나 다른 댓글을 작성할 필요가 없도록 청중을 표시 할 수 있습니까? SO 모드에 대한 질문
Pavneet_Singh

나는 내 의견을지지한다. 내가 답장을했지만 ... 삭제 한 후 여기에이 질문을 게시 한 이유가 질문에 대해 95 % 주제를 벗어 났으며 이전 답변의 5 % 반복이라는 사실을 변경하지 않습니다. 낭비한 노력의 결과를 저장하려면 하드 드라이브에 저장하는 것이 더 적절할 것입니다. 또는 관련된 다른 질문을 찾으십시오.
Stephen C

중재자에게 불만이 있으시면 meta.stackoverflow.com에서 접수하십시오. 그리고 증거를 제공하십시오. 여기서 제가하려는 것은 정리 >>이 << Q & A입니다.
Stephen C

나는 당신의 견해를 이해하지만 일부 독자에게 도움이 될 수있는 추가 값으로 예제와 함께 유니 코드 변환의 세부 사항을 무시하는 사실을 이해할 수 없으므로이 답변을 유지하고 싶습니다. 이야기). 힘이나 지원 없이는 이런 일을하기가 쉽지 않아서 많은 시간과 노력이 소요되는 메타와 유사한 장소는 피합니다. 나는 내면의 평화를 지키는 것을 선호합니다.
Pavneet_Singh

0

Boann의 대답 은 정확 하지만 할당 컨텍스트에 나타날 때 상수 표현 의 경우에 적용되는 복잡함이 있습니다 .

다음 예를 고려하십시오.

  char x = 'a' + 'b';   // OK

  char y = 'a';
  char z = y + 'b';     // Compilation error

무슨 일이야? 그들은 같은 것을 의미하지 않습니까? 첫 번째 예에서 int를 a char에 할당하는 것이 합법적 인 이유는 무엇입니까?

상수식이 할당 컨텍스트에 나타나면 Java 컴파일러는 식의 값을 계산하고 할당중인 유형의 범위에 있는지 확인합니다. 그렇다면 암시 적 축소 기본 변환 이 적용됩니다.

  • 첫 번째 예제 'a' + 'b'에서은 상수 표현식이고 해당 값은에 맞으 char므로 컴파일러는 int표현식 결과를 char.

  • 두 번째 예에서는 y변수이므로 y + 'b'상수 표현식이 아닙니다. 따라서 Blind Freddy 는 값이 맞는 것을 알 수 있지만 컴파일러는 암시 적 축소를 허용하지 int않으며 char.

이 컨텍스트에서 암시 적 축소 기본 변환 이 허용되는 경우에 대한 몇 가지 다른주의 사항 이 있습니다. 자세한 내용은 JLS 5.2JLS 15.28 을 참조하십시오.

후자는 상수 표현식에 대한 요구 사항을 자세히 설명합니다 . 당신이 생각하는 것과 다를 수 있습니다. (예를 들어, 도움이되지 않는 y것으로 선언 하면됩니다 final.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.