int
, byte
, short
, long
, float
, double
, boolean
, char
로 8가지가 있다.
객체로 간주되지 않는다.
선언된 값이 스택에 바로 저장된다.
primitive 데이터 타입은 크기의 제한이 있다.
제한을 넘어서는 값을 담게되면 발생한다.
integer overflow, underflow
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MAX_VALUE + 1); // overflow
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MIN_VALUE - 1); // underflow
}
floating point overflow, underflow
부동 소수점 방식의 경우 1을 더하는 방식으로는 overflow 가 발생하지 않는다.
비트를 변경하여 발생을 확인할 수 있다.
public static void main(String[] args) {
System.out.println(Double.MAX_VALUE);
System.out.println(Double.MAX_VALUE * 2); // overflow
System.out.println(Double.MIN_VALUE);
System.out.println(Double.MIN_VALUE / 2); // underflow
}
primitive 데이터 타입을 Wrapper Class 로 변환해야 할 때가 있다.
이를 자동으로 변환해주는 것을 Autoboxing 이라 한다.
Character c = 'c';
Integer i = 1;
263.3 을 2진수로 표현해보자
263 = 100000111
0.3 = 0.3 x 2 = 0.6 ... 0
0.6 x 2 = 1.2 ... 1
0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
...
소수점이 계속 존재
무한히 반복된다.
0.3 = 0.01001100110011...
가장 근사치의 값을 저장해야 한다.
저장하는 방식은 2가지가 있다.
고정 소수점
정수를 표현하는 bit 수와 소수를 표현하는 bit 수를 미리 정해놓고 표현
만약 부호 1bit, 정수 16bit, 소수 15bit 인 시스템이라면,
263.3 = (0)0000000100000111.010011001100110
정수 bit 이 커지면 큰 숫자로 표현할 수 있지만, 정밀한 숫자 표현 X
소수 bit 이 커지면 정밀한 숫자를 표현할 수 있지만, 큰 숫자 표현 X
부동 소수점
지수 8bit 과 가수 23bit 으로 나누어 표현
263.3 = 1.00000111010011001100110 * 2^8
으로 표현
2^8
➔ 지수부
bias 127 이 있으므로, 2^8
을 표현하려면 127 + 지수
10000111 (127 + 8)
00000111010011001100110
➔ 가수부
float
자료형
double
자료형
float
대비 2배의 byte를 사용하여 정밀도를 더욱 높였다.
0을 표현하는 방법
가장 작은 수 표현
지수 bit 가 모두 0이어도, 가수 bit가 모두 0이 아니면,
유효 bit 을 0.xx...
로 설정하고
1.xx...
로, 1로 시작한다.지수값을 -126으로 설정한다.
무한수 표현
inf
를 나타낸다.최대값 표현
부동 소수점의 오차
작은 bit 로 큰 수를 표현할 순 있지만 값이 커지면 정확성이 떨어진다.
float
자료형의 가수 bit 크기는 23bit 로 정수값 자리수가 23을 넘어가면 작은 자릿수들을 표현할 수 없다.
8가지 primitive type 을 제외한 나머지 타입
클래스, 배열, 인터페이스, 열거 타입등이 모두 reference type 이다.
실제 값이 저장되지 않고, 자료가 저장된 Heap 의 주소값을 스택에 저장
스택에 할당되는 메모리크기는 주소값을 저장하기 위한 4byte 이다.
코드에서 상수로 지정하는 모든 값
integer, float, double, long, String, char, boolean, null 등 직접 표현하는 모든 값들이 리터럴이 될 수 있다.
작은 리터럴을 큰 자료형에 담을 수 있지만, 큰 리터럴을 작은 자료형에 담을 순 없다.
double d = 123.456; // 123.456
double d2 = 123.456f; // 123.45600128173828
long l = 123;
long l2 = 123L;
int i = (short) 1;
int i2 = (byte) 1;
상대적으로 작은 리터럴을 큰 자료형에 담을 수 있다.
float f = 123.456;
float f2 = 123.456d;
int i = 123L;
int i2 = 1234567890123;
short s = 32768;
byte b = 128;
// 모두 컴파일 에러 발생
상대적으로 큰 리터럴을 작은 자료형에 담을 수 없다.
문자열 리터럴은 String Constant Pool 영역에 할당된다.
문자열 리터럴의 경우 내부적으로 String 클래스의 intern()
메서드를 호출한다.
만약 String Constant Pool 에 이미 문자열 리터럴이 존재하는 경우, 존재하는 객체의 주솟값을 반환한다.
만약 String Constant Pool 에 문자열 리터럴이 존재하지 않는 경우, 새로 객체를 String Constant Pool 에 생성한 후 해당 객체의 주솟값을 반환한다.
new 연산자로 생성한 경우엔, 일반 객체들처럼 메모리의 Heap 영역에 할당된다.
public void string() {
String name = "lxxjn0";
String name1 = "lxxjn0"; // String 클래스의 intern() 메서드 동작
String name2 = new String("lxxjn0");
String name3 = new String("lxxjn0");
}
name
,name1
은 같은 객체를,name2
,name3
는 다른 객체를 가리킨다.
String s1 = "hi";
String s2 = new String("hi");
System.out.println(s1.equals(s2)); // true
System.out.println(s1 == s2); // false
System.out.println("s1 addr = " + System.identityHashCode(s1)); // s1 addr = 2144838275
System.out.println("s2 addr = " + System.identityHashCode(s2)); // s2 addr = 596470015
String intern = s2.intern();
System.out.println("s2 addr = " + System.identityHashCode(intern));
- 문자열 리터럴과 new 로 만든 문자열은 다른 객체를 가리키므로
==
비교에서false
를 반환한다.intern()
메서드 호출 시, String Constant Pool 에 있는 문자열 객체 (문자열 리터럴) 의 주소값을 반환한다.
문자열 리터럴은 불변이기 때문에 이와같이 여러 레퍼런스가 같은 문자열 리터럴을 참조하여도 thread-safe 하다.
출처
자바 primitive, reference 자료형 그림과 표 (인파 님)
https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EB%B3%80%EC%88%98%EC%9D%98-%EA%B8%B0%EB%B3%B8%ED%98%95-%EC%B0%B8%EC%A1%B0%ED%98%95-%ED%83%80%EC%9E%85
자바 primitive (Baeldung)
https://www.baeldung.com/java-primitives
부동 소수점의 유래 (modolee 님)
https://steemit.com/kr/@modolee/floating-point
부동 소수점의 이해 (콘파냐 님)
https://thrillfighter.tistory.com/349
자바 overflow, underflow (그날그날메모 님)
https://memo-the-day.tistory.com/121
IEEE Standard 754 Floating Point Numbers (GeeksforGeeks)
https://www.geeksforgeeks.org/ieee-standard-754-floating-point-numbers/
자바의 literal (Baeldung)
https://www.baeldung.com/java-literals
자바의 문자열 리터럴 (테코블 스티치 님)
https://tecoble.techcourse.co.kr/post/2020-09-07-dive-into-java-string/