자바는 기본형과 참조형이 있습니다.
기본형은 Boolean, Numeric(Integral, Character)이 있고
참조형은 Class, Interface, Array, Enum 등이 있습니다.
Primitive Type
Primitive Type
java에서는 primitive type이 8가지로 분류합니다.
기본 자료형은 사용 전에 선언되어있어야 하며, OS에 따라 자료형의 길이가 변하지 않습니다.
비객체 타입으로 null값을 가질 수 없습니다. null이 필요하면 Wrapper Class를 활용합니다.
wrapper class는 기본 클래스로 감싼 형태입니다.
final로 정의되어있기때문에 수정은 불가하고 사용만 가능합니다.
기본형 대응 래퍼 클래스
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Char
boolean Boolean
스택 메모리에 저장되는 타입입니다.
- boolean
- 논리형인 boolean의 기본값은 false이며 참과 거짓을 저장하는 타입입니다. 주로 yes/no, on/off 등의 논리 구현에 주로 사용되며 두가지 값만 표현하므로 가장 크기가 작습니다.
- boolean은 실제로 1bit면 충분하지만, 데이터를 다루는 최소 단위가 1byte이므로 메모리 크기가 1byte입니다.
- byte
- byte는 주로 이진데이터를 다루는데 사용되는 타입입니다.
- short
- short는 C언어와의 호환을 위해 사용되는 타입으로 잘 사용되지는 않는 타입입니다.
- int
- int 형은 자바에서 정수 연산을 하기 위한 기본 타입입니다. 즉, byte 혹은 short 의 변수가 연산을 하면 연산의 결과는 int형이 됩니다.
- long
- 수치가 큰 데이터를 다루는 프로그램에서 주로 사용합니다.
- long 타입의 변수를 초기화 할 떄에는 정수값 뒤에 알파벳 L을 붙여서 long 타입(즉, 8byte)의 정수 데이터임을 알려주어야 합니다. 만일 정수값이 int의 값의 저장 범위를 넘는 정수에서 L을 붙이지 않는다면 컴파일 에러가 발생합니다.
- float, double
- 실수를 가수와 지수 형식으로 저장하는 부동소수점 방식으로 저장됩니다.
- 가수를 표현하는데 있어 double형이 float형보다 표현 가능 범위가 더 크므로 double형이 보다 정밀하게 표현할 수 있습니다.
- 자바에서 실수의 기본 타입은 double형이므로 float형에는 알파벳 F를 붙여서 float 형임을 명시해주어야 합니다.
Reference Type
Reference Type
Primitive Type이 아닌 타입들이 Reference Type입니다.
new로 생성되는 것들은 Heap영역에 생성되고, GC로 인해 메모리에서 해제됩니다.
빈 객체를 의미하는 null이 존재하며 runtime에 체워지곤합니다.
예외) String Class
참조형에 속하지만 기본적인 사용은 기본형처럼 사용하는 것입니다. 그리고 불변객체입니다. String class는 값을 변경해주는 메소드가 존재하지만 해당 메소드를 변경하면 새로운 메소드를 만드는 것과 동일합니다.
따라서 기본형의 비교는 "=="으로 가능하지만 String 값은 .equals()를 사용해야합니다.
int i = null; // 불가능
Integer integer = null; // 가능
List<int> i; // 제네릭도 불가능
List<Integer> integer; // 가능
Integer a = Integer.valueOf(2);
Integer b = Integer.valueOf(2);
// Integer a = new Integer(2);
// Integer b = new Integer(2);
// a와 b 의 주소 확인하려면
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(a == b);
// Integer를 new로 정의했을 때 다른 주소로 들어가게됩니다.
// 하지만 자바 9 이후로 deprecate되었기에 사용은 되지만 red line이 생깁니다.
// valueOf 같은 경우 -127~128까지 범위에 대해 캐시를 적용해 있다면 값으로 사용하고 없다면 객체를 new로 생성합니다.
이러한 오토박싱, 오토 언박싱은 JDK 1.5부터는 자바 컴파일러가 자동으로 처리해줍니다.
하지만 내부적으로 추가 연산 작업을 진행합니다. 따라서 시간을 단축해주기 위해 이러한 처리가 있는지 알 필요가 있습니다.
public static void main(String[] args) {
long t = System.currentTimeMillis();
Long sum = 0L;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println("실행 시간: " + (System.currentTimeMillis() - t) + " ms");
}
// 실행 시간 : 19 ms
public static void main(String[] args) {
long t = System.currentTimeMillis();
long sum = 0L;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println("실행 시간: " + (System.currentTimeMillis() - t) + " ms") ;
}
// 실행 시간 : 4 ms
성능이 중요하고 대량의 데이터나 많은 계산을 다루어야 하는 상황에서는, 원시 데이터 유형을 직접 사용하는 것이 실행 시간이 더 빠를 수 있습니다.
그럼 여기서 질문!!
orm을 사용할 때, domain은 언제 int를 사용하는가?
@Collunm(nullabe=false)
private int a;
즉, null값이 사용될 우려가 없는 경우 사용하게 된다면 메모리 효율을 최적화해서 사용할 수 있습니다.
하지만 a가 int이기에 연산할 때, 자료형을 확인하고 연산할 필요가 있다는 점!
참조 : https://gyoogle.dev/blog/computer-language/Java/Primitive%20type%20&%20Reference%20type.html