참고: https://en.wikibooks.org/wiki/Java_Programming/Primitive_Types
참고 서적: 자바 퍼즐러
자바 개발자라고 하기에는 자바에 대한 기초 지식이 부족하다고 느낀다.
char가 1바이트 일거라고 생각했는데 2바이트라니.
이 김에 정리하자
primitive type
type | size (bits) | min value | max value | Precision | example |
byte | 8 | -128 | 127 | From +127 to -128 | byte b = 65; |
char | 16 | 0 | 2^16-1 | All Unicode characters[1] | char c = 'A'; char c = 65; |
short | 16 | -215 | 2^15-1 | From +32,767 to -32,768 | short s = 65; |
int | 32 | -231 | 2^31-1 | From +2,147,483,647 to -2,147,483,648 | int i = 65; |
long | 64 | -263 | 2^63-1 | From +9,223,372,036,854,775,807 to -9,223,372,036,854,775,808 | long l = 65L; |
float | 32 | 2-149 | (2-2-23)·2127 | From 3.402,823,5 E+38 to 1.4 E-45 | float f = 65f; |
double | 64 | 2-1074 | (2-2-52)·21023 | From 1.797,693,134,862,315,7 E+308 to 4.9 E-324 | double d = 65.55; |
boolean | 8 | -- | -- | false, true | boolean b = true; |
void | -- | -- | -- | -- | -- |
자바는 c, c++언어완는 다르게 unsigned 자료형이 없다.
따라서 할당 바이트중에 가장 상위 비트 (가장 왼쪽 비트)는 부호 비트이다.
%연산에 대한 오해
1%3 의 결과는 무엇일까? 1이다.
그렇다면 -1%3의 결과는 무엇일까?
나는 당연히 1일 것이라고 생각했다.
하지만 결과는 -1이다.
a%b의 결과는 a의 부호에 따라간다.
왜냐하면 (a/b)*b + a%b == a 이니까.
이 점을 간과하면 아래와 같은 코드를 작성하게 될 수도 있다.
boolean isOdd(int target) {
return target%2 == 1;
}
정수는 기본적으로 int, 실수는 기본적으로 double 자료형으로 표현한다.
그래서 다른 정수 자료형으로 정수를 표현하기 위해서는 자료형 변환을 해야한다.
이 때 long으로 표현하기 위해 제공되는 접미사가 L(소문자도 가능)이다. 가급적 소문자는 쓰지 않도록! (숫자 1이랑 헷갈리니까..)
마찬가지로 다른 실수 자료형으로 실수를 표현하기 위해서는 자료형 변환을 해야한다.
이 때 float으로 표현하기 위헤 제공되는 접미사가 F(소문자도 가능)이다.
자바는 음수 정수를 2의 보수로 표현한다.
2의 보수는 1의 보수에서 1을 더한 값이다.
1의 보수가 비트로 표현하기에는 간단할 수도 있지만 연산을 할 때는 2의보수가 더 편하다.
따라서 자바는 2의 보수로 음수 정수를 표현한다.
자료형 확장, 축소
이항 연산자로 연산을 하는데 두 피연산자의 자료형이 다르다면 어떻게 될까?
기본적으론는 큰 자료형으로 변환이 된다.
(예외적으로 두 피연산자 중 하나가 String이면 다른 피연산잔는 String으로 변환되어 연산된다.)
이 때 자료형 축소, 변환이라는게 일어나는데 단순하게는 비트수가 늘어나는 것이라고 생각하면 된다.
이 때 주의할 것은, 부호가 있는 연산자(ex. int, short)가 확장이 필요할 때 부호의 확장이 일어나고, 부호가 없는 연산자(ex. char)는 0의 확장이 일어난다.
좀 지저분한 문제지만
System.out.println((int)(char)(byte)-1);
이 출력은 65535 == 2^16-1이다.
이유는 -1은 2의 보수로 인해 모든 비트가 1이다. 따라서 byte로 표현되면 1이 8개 있는 비트다.
이를 char로 형변환할 때 byte는 부호가 있는 자료형이기 때문이 부호 확장이 일어나서 16비트가 모두 1이 된다. (물론 char는 모두 양수로 표현하기에 값은 2^16-1 이다.)
이를 int로 다시 변환할 때 char는 부호가 없는 자료형이라서 0의 확장이 일어나고 결과적으로 상위 2바이트는 0, 하위 2바이트는 1이 된다.
따라서 결과는 2^16-1인 65535이다.
복합연산자
+=과 같은 연산자를 복합 연산자라고 부르는데,
x +=y는 x = x + y의 결과와 같다
라고 배웠지만, 반틈만 맞는 답 같다.
복합 연산자 또한 대입 연산자이다.
만약 x가 int, y가 long 자료형이라면 x+=y는 문제 없이 컴파일 되지만 x = x+y는 컴파일 에러가 발생한다.
이유는 long자료형을 x에 대입할 수 없기 때문이다.
x+=y가 문제가 없는 이유는 복합 연산자는 왼쪽의 연산자로 자동 형변환을 해주기 때문이다.
char 형은 사칙연산에서 int로 취급된다.
문자는 사칙연산시에는 2바이트의 숫자로 인식된다.
따라서 아래의 출력 값은 문자가 아닌 숫자이다.
System.out.println('a'+'a');
// aa 출력이 아닌, 특정 문자 출력도 아닌, 194가 출력된다.
'언어 > 자바' 카테고리의 다른 글
자바 클래스 구성 시 주의할 점. (0) | 2019.08.18 |
---|---|
자바 자료형 사용 시 주의 (0) | 2019.08.15 |
[Effective java] equals를 재정의하려거든 hashCode도 재정의하라 (0) | 2019.07.24 |
[Effective java] equals는 일반 규약을 지켜 재정의하라. (0) | 2019.07.22 |
java.util.Date와 LocalDateTime (0) | 2019.07.20 |