※ Java의 정석 기초편을 공부하며 기억하고 싶은 특이점들만 기록, 정리해 놓은 노트이다.
※ 노션 페이지를 복사해오다 보니 식과 포맷이 엉성한 곳이 있다.
변수
: 하나의 값을 저장할 수 있는 공간.
저장된 값을 다른 값으로 교체할 수 있다.
상수
: 값을 한 번 저장하면 변경할 수 없는 저장공간.
final int MAX_VALUE;와 같이 final 키워드를 붙여주면 된다.
리터럴
: 그 자체로 값을 의미하는 것.
12, ‘A’와 같은 원래의 ‘상수’들을 부르기 위해 따로 만든 용어.
리터럴의 타입과 접미사
변수에 타입이 있는 것처럼 리터럴에도 타입이 있다. 변수의 타입은 저장될 ‘값의 타입(리터럴의 타입)’에 의해 결정되므로, 만일 리터럴에 타입이 없다면 변수의 타입도 필요없을 것이다.
종류 | 리터럴 | 접미사 |
논리형 | false, true | 없음 |
정수형 | 123, 0b0101, 077, 0xFF, 100L | L (또는 l) |
실수형 | 3.14, 3.0e8, 1.4f, 0x1.0p-1 | f (또는 F), d (또는 D) |
문자형 | ‘A’, ‘1’, ‘\n’ | 없음 |
문자열 | “ABC”, “123”, “a”, “true” | 없음 |
정수형
- long타입과 int타입만 구분한다. 접미사가 없으면 int타입의 리터럴이다.
- byte과 short타입의 변수에 값을 저장할 때는 int타입의 리터럴을 써주면 된다.
- ⇒ 결론: long타입 변수에 값을 넣을 때만 접미사 ‘L(또는 l)’을 붙여주자.
- 8진수로 표현된 리터럴: 접두사 ‘0’를 붙인 수. int octNum = 010;같은 식으로.
- 16진수로 표현된 리터럴: 접두사 ‘0x’ 또는 ‘0X’를 붙인 수. long hexNum = 0xFFL;
- 중간에 구분자 ’_’를 넣을 수도 있다 (JDK 1.7부터 가능하게 됨):long hex = 0xFFFF_FFFF_FFFF_FFFFL;
- long big = 100_000_000_000L;
실수형
- 접미사가 없으면 double타입 리터럴이다.
문자형
- ''안에 반드시 하나의 문자가 있어야 한다.
- 공백 문자(blank) ' '은 괜찮음.
문자열
- ""안에 아무런 문자도 넣지 않아도 된다.
- 문자열 String 클래스만 특별히 new연산자 없이 객체를 생성하는 것이 허용된다.
- String name = "Java";
- 문자열 + (아무 타입)의 연산 결과는 무조건 문자열이 된다.
- ⇒ 문자열 + (아무 타입) → 문자열 + 문자열 → 문자열
타입 간의 변환 방법
숫자 → 문자
: 숫자에 ‘0’을 더한다.
(char)(3 + ‘0’) → ‘3’
해설: 덧셈 연산을 하기 위해 char의 두 얼굴 중 short타입 값으로 연산이 수행된다. 피연산자들이 int 이하 자료형이므로 int로 자동 형변환되어 계산되게 되고, 그리고서 char타입으로 명시적 형변환이 되어 결과 타입은 char가 되게 됨.
문자 → 숫자
: 문자에서 ‘0’을 뺀다.
‘3’ - ‘0’ → 3
해설: 뺼셈 연산자로 인해서 char의 두 얼굴 중 short타입 값으로 계산이 수행된다. 근데 int이하 자료형은 int로 자동변환되어 연산이 수행되고, 따라서 결과 타입도 int.
숫자 → 문자열
: 숫자에 빈 문자열(””)을 더한다.
3 + “” → “3”
해설: 문자열 우세법칙에 의하여.
문자열 → 숫자
Integer.parseInt("3") → 3
Double.parseDouble("3.14") → 3.14
문자열 → 문자
"3".charAt(0) → ‘3’
문자 → 문자열
: 빈 문자열을 더한다.
'3' + "" → “3”
해설: 문자열 우세법칙에 의하여.
오버플로우
: 연산과정에서 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것.
에러가 발생하지는 않지만 값의 손실이 발생한다.
저장공간을 넘어간 비트 1들은 버려진다.
- 최대값 + 1 → 최소값
- 최소값 - 1 → 최대값
- 왜 1바이트의 정수형이 $-2^7$ ~ $2^7 -1$까지의 범위만 갖는 거지? ⇒ 해결함!
- 오 부호비트라는게 있어서 가장 큰 자리가 0이면 양의부호, 1이면 음의부호가 된다고 하는 것 같다. 아 그래서…
- 부호 있는 정수는: 가장 큰 8번째 비트자리, 즉 $2^7$의 자리가 0에서 1로 바뀌는 순간부터 음수라고 본다. 즉, 0111_1111(2)가 1000_0000(2)가 되는 순간부터 이 수는 사실 -1000_0000(2)라고 계산하는 것이다. 그리고 그 이후부터 1이 커질때마다 1이 커진다…
- 어쨌든 양수로써 도달할 수 있는 가장 큰 수가 $2^7-1$이 된다는 것은 알겠다.
- 음수는 $2^7$자리부터 딱 시작되는 것도 알겠다.
- 그래서 n비트 정수형의 표현범위가 $-2^{n-1}$ ~ $2^{n-1}-1$ 이 되는 것이다!
- 쉽게 설명해서, 1바이트 정수형이 있을 때
- 8비트의 자리가 있으면 $2^0$부터 시작해서 가장 큰 8번째 자리가 $2^7$이 되는 것은 알겠다. 그러면 넘어갈 수 없는 자리 $2^8$보다 하나 작은 수가 한도가 되어야 하는 것 아닐까? 즉, 범위가 $-2^8$-1 ~ $2^8$-1이어야 하지 않을까?
부호있는 정수는 부호비트가 0에서 1이 될 때 오버플로우가 발생한다.
= 최소값: $-2^7$, 최대값: $2^7 -1$ (1바이트형인 경우)을 무한 도돌이 하는 것.
부호없는 정수는 최소값: 0, 최대값: $2^8-1$(1바이트형인 경우)을 기점으로 오버플로우가 발생하고 무한 도돌이 한다.
대표적으로 똑같이 2바이트 형인 short타입은 부호있는 정수형이고, char타입은 부호없는 정수형이다.
⇒ short의 최소, 최대: $-2^{15}$ ~ $2^{15}-1$ = -32,768 ~ 32,767
⇒ char의 최소, 최대: $0$ ~ $2^{16}-1$ = 0 ~ 65.535
자바에서 사용하는 키워드
참고: Java의 정석 기초편