티스토리 뷰
목차
Summary
기본형과 참조형 데이터 타입의 차이에 대해서만 선 요약하고 들어간다.
요약 이후의 글은 둘의 차이 뿐 아니라 각각의 특성에 대해서도 조금 더 다루고 있다.
Primitive Variables | Reference Variables | |
개수 | 8 | 무제한(기본형을 제외한 전부) |
크기 | 1, 2, 4, 8byte(타입마다 다름) | 4, 8byte(JVM에 따라 다름) |
저장 데이터 | 데이터 값 | 데이터의 주소값 |
데이터 저장 위치 | Call Stack | Heap |
산술연산 | 가능 | 불가능 |
null 값 | 불가능 | 가능 |
비교 연산자 | == | equals() |
Primitive Variables
자바는 아래의 8가지 기본형 타입을 제공한다.
타입 | 할당되는 메모리 크기 | 기본값 | 표현 범위 | |
논리형 | boolean | 1 byte | false | true, false |
정수형 | byte | 1 byte | 0 | -128 ~ 127 |
short | 2 byte | 0 | -32,768 ~ 32,767 | |
int(기본) | 4 byte | 0 | -2,147,483,648 ~ 2,147,483,647 | |
long | 8 byte | 0L | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | |
실수형 | float | 4 byte | 0.0F | (3.4 X 10-38) ~ (3.4 X 1038) 의 근사값 |
double(기본) | 8 byte | 0.0 | (1.7 X 10-308) ~ (1.7 X 10308) 의 근사값 | |
문자형 | char | 2 byte (유니코드) | '\u0000' | 0 ~ 65,535 |
기본형 타입은 아래와 같은 특징을 지니며,
- 메모리에 값 자체를 저장
- 산술 계산 가능
- null 값을 가질 수 없음(=객체 타입이 아님)
표현 범위보다 큰 값을 저장하려고 하면 형 변환을 요구하는 에러가 난다.
byte i = 128;
java: incompatible types: possible lossy conversion from int to byte
Type Conversion
형 변환의 경우 표현 범위가 작은 변수 -> 큰 변수의 변환은 컴파일러에 의해 자동으로 이루어지며,
(byte < short < int < long < float < double)
public class PrimitivePractice {
public static void main(String[] args) {
byte a = 1;
short b = a;
int c = b;
long d = c;
float e = d;
double f = e;
System.out.println(f);
}
}
1.0
반대의 경우 타입을 명시하지 않으면 에러가 난다.
public class PrimitivePractice {
public static void main(String[] args) {
int a = 1;
// short b = a; // 에러
short b = (short) a;
System.out.println(b);
}
}
1
위와 같은 명시적 형 변환의 경우, 오버플로우 혹은 언더플로우의 가능성이 있으므로 주의해야 한다.
public class PrimitivePractice {
public static void main(String[] args) {
int a = 32768;
short b = (short) a;
System.out.println(b);
}
}
-32768 // 오버플로우 발생
또한 연산 결과를 담을 때 역시 표현 범위를 넘어서면 오버플로우가 일어나게 된다.
public class PrimitivePractice {
public static void main(String[] args) {
byte i = 127;
i++;
System.out.println(i);
}
}
-128
마지막으로 boolean 타입의 경우 다른 타입으로의 형 변환이 불가능하며,
char 타입의 경우 음수 범위를 다룰 수 없으므로 같은 크기의 short로 형 변환 시 반드시 명시해주어야 한다.
public class PrimitivePractice {
public static void main(String[] args) {
char a = 'a';
// short b = a; // 에러
short b = (short) a;
System.out.println(b);
}
}
97
Floating Point & Accuracy Problem
이어서 실수형 타입 float과 double에 대해서 조금 더 알아보자.
두 데이터 타입은 각각 실수를 부동소수점 방식으로 나타내 근사치의 계산을 빠르게 하기 위한 자료형이다.
여기서 부동소수점 방식이란 아래와 같은 표현 방식을 말하며,
가수(Significand)부분의 저장 용량에 따라 데이터 타입의 정확도가 정해진다.
물론 실제 컴퓨터에 데이터가 저장될 때는 위와 같은 십진수가 아니라 이진수의 형태로 저장되며,
타입별 가수와 지수(Exponent)에 할당되는 메모리 및 정확도는 아래와 같다.
타입 | 부호 | 지수 | 가수 | 유효 자릿수 |
float(32bit) | 1bit | 8bit | 23bit | 7 |
double(32bit) | 1bit | 11bit | 52bit | 16 |
또한 앞서 말한 바와 같이 어디까지나 근삿값에 대한 계산이므로 언제나 오차가 존재할 가능성이 있으며
System.out.println(0.1f * 0.1f);
0.010000001
교환 법칙은 항상 성립하지만 결합 법칙과 분배 법칙은 항상 성립하지는 않는다는 특성이 있다.
참고로 오차 없이 큰 수를 다루고 싶은 경우에는 BigDecimal(실수형), BigInteger(정수형) 등의 타입을 사용하면 된다.
2022.10.09 - [Development/Java] - [Java]무한히 큰 숫자 다루기, BigInteger
Wrapper Classes
계속해서 기본형을 객체 타입으로 이용해 null을 저장하고 싶으면 래퍼(Wrapper) 클래스를 사용해야 한다.
public class PrimitivePractice {
public static void main(String[] args) {
Byte i = null;
System.out.println(i);
}
}
null
여기서 래퍼 클래스란 이름 그대로 기본형 데이터 타입을 객체 형태의 타입으로 포장하는 클래스를 가리키며,
기본형을 래핑하는 과정을 박싱(Boxing), 반대 과정을 언박싱(Unboxing)이라 부른다.
각 기본형에 대한 래퍼 클래스는 아래와 같다.
Primitive Types | Wrapper Classes |
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
끝으로 JDK 1.5 이전까지는 박싱과 언박싱을 일일이 입력해주어야 했으나
지금은 자동 박싱/언박싱(Auto Boxing/Unboxing)이 지원되므로 편하게 형 변환을 할 수 있다.
public class PrimitivePractice {
public static void main(String[] args) {
byte i = 1;
Byte j = i;
System.out.println(j);
}
}
1
Reference Variables
참조형 데이터 타입은 위에서 알아본 기본형을 제외한 자바의 모든 타입을 가리킨다.
많이 쓰이는 타입은 아래와 같으며,
타입 | 예시 | 기본값 | 할당되는 메모리 크기 |
Array | int[] arr = new int[5]; | 0 | 4byte(32bit JVM) / 8byte(64bit JVM) →데이터 주소를 저장 |
Enumeration | Null | ||
Class | String str = "String"; Member member = new Member(); |
Null | |
Interface | Null |
클래스에서 볼 수 있듯이 사용자 정의 타입도 포함한다.
이어서 참조형 데이터 타입은 기본형 데이터 타입과 달리 다음과 같은 특징을 갖는다.
- 메모리에 데이터 주소(참조값)를 저장 → 실제 값은 힙 메모리에 위치
- 산술 연산 불가능
- null 값을 가질 수 있음 → NPE에 대한 대비 및 처리 필요
추가로 앞서 알아봤던 박싱 과정 역시 기본형을 참조형으로 변환해주기 때문에 산술연산이 불가능해야 하지만
자동 박싱/언박싱 덕분에 연산이 가능하다는 예외적인 특징을 가지고 있다.
여기서 잊지 말아야 할 점은 참조형은 데이터 자체가 아닌 주소값을 저장하기 때문에
비교 연산자(특히 ==)를 사용할 때 주의해야 한다는 것이다.
public class ReferencePractice {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(a == b); // true
System.out.println(a == c); // false
System.out.println(a.equals(c)); // true
}
}
abc
abc
abc
true
false
true
같은 "abc" 값을 가졌지만 a와 c는 다른 주소를 가리키고 있으므로 false를 리턴하게 된다.
따라서 참조형을 다룰 땐 데이터 값을 비교해주는 equals()메서드를 사용하는 습관을 들이는 것이 좋다.
'Development > Technical Interview' 카테고리의 다른 글
[면접 준비 - Cloud]PaaS, Docker, 그리고 (2) | 2022.12.09 |
---|---|
[면접 준비 - Java]JVM 구조(1), JVM Workflow (8) | 2022.10.30 |
[면접 준비 - Java]메서드 오버로딩 vs. 메서드 오버라이딩 (2) | 2022.10.25 |
[면접 준비 - Java]자녀 클래스에서 부모 클래스 생성자 호출 (0) | 2022.10.25 |
[면접 준비 - Java]생성자(Constructor) (2) | 2022.10.24 |
[면접 준비 - Java]클래스(Class)와 객체(Object) (2) | 2022.10.23 |
- Total
- Today
- Yesterday
- a6000
- 유럽여행
- 세모
- 기술면접
- 동적계획법
- Backjoon
- java
- 세계여행
- 파이썬
- 지지
- spring
- 자바
- 스트림
- 맛집
- 리스트
- 남미
- 백준
- RX100M5
- Algorithm
- 세계일주
- 면접 준비
- 야경
- BOJ
- 유럽
- 중남미
- 칼이사
- Python
- 여행
- 스프링
- 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |