Java - 데이터 타입
1. 데이터 타입(Date Type)
이전 글, [JAVA - 변수]를 통해, 자바에서 변수를 만들고 사용하는 방법에 대해 알아보았습니다. int 타입의 변수를 만든 다음 정수 값을 쓰고 읽는 방법에 대해 설명했는데요. 하지만 자바로 프로그래밍을 할 때, 항상 정수 타입의 변수만 사용하는 것은 아니겠죠. 이름을 출력하기 위해 문자열을 다룰 수도 있고, 소수점이 포함된 실수 값을 처리해야 할 수도 있습니다.
이런 경우, int 타입이 아닌, 다루고자 하는 값을 처리할 수 있는 적절한 데이터 타입을 사용해야 하는데요. 그래서 이 글에서는 자바에서 제공하는 데이터 타입의 종류에 대해 소개하고, 몇 가지 예제를 통해 데이터 타입으로 선언한 변수에 값을 읽고 쓰는 예제와 결과를 확인해보겠습니다.
2. 자바의 데이터 타입.
자바에서 사용할 수 있는 데이터 타입은 크게, "기본 데이터 타입(Primitive Data Type)"과 "기본이 아닌 데이터 타입(Non-primitive Data Type)"으로 나눌 수 있습니다. ("Non-primitive Data Type"을 사전적 의미 그대로 "기본이 아닌 데이터 타입"이라고 번역했지만, 사실 "기본 데이터 타입"와 구분되는 특징에 따라 일반적으로 "참조 데이터 타입(Reference 데이터 Type)"이라는 용어를 사용합니다.)

2.1 기본 데이터 타입. (Primitive Data Type)
"기본 데이터 타입(Primitive Data Type)"은 자바 언어에서 기본적으로 제공하는 데이터 타입을 말합니다. 자바 프로그램에서 관리되는 데이터를 구성하는데 있어 가장 기초가 되는 데이터 타입을 나타내기 때문에 "기본 데이터 타입(Primitive Data Type)"이라고 하며, "Primitive"라는 단어의 사전적 의미에 따라 "원시 데이터 타입"이라고 부르기도 합니다.
정수 값을 나타내는데 사용하는 byte, short, int, long 타입, 실수 값을 위해 사용되는 float, double, 문자를 위한 char, 참(true) 또는 거짓(false)으로 표현되는 논리 값을 위한 boolean 등이 기본 데이터 타입(Primitive Data Type)에 해당합니다.

2.2 참조 데이터 타입. (기본이 아닌 데이터 타입, Non-primitive Data Type)
"기본 데이터 타입(Primitive Data Type)"을 제외한 모든 데이터 타입은 "기본이 아닌 데이터 타입(Non-primitive Data Type)"에 속합니다. 사실 "non-primitive"를 직역하여 "기본이 아닌"이라고 적긴 했지만, 일반적으로 "참조 데이터 타입(Reference Data Type)" 이라고 부릅니다. 왜냐하면 "기본 데이터 타입(Primitive Data Type)"이 값(value)을 가지는 것과 다르게 "기본이 아닌 데이터 타입(Non-primitive Data Type)"은 객체에 대한 참조(reference)를 가지는 특징으로 구분되기 때문이죠.
그런데 아마도, "응? 객체에 대한 참조(reference)를 가진다는 게 무슨 말이지?"라는 의문이 들텐데요, 지금 당장 그 의미를 몰라도 상관없습니다. "객체 참조(reference)"에 대한 설명은 앞으로 다양한 설명과 예제를 통해 소개하게 될테니, 지금은 그냥 "기본 데이터 타입(Primitive Data Type)"을 제외한 데이터 타입을 "참조 데이터 타입(Reference Data Type)"이라고 한다는 내용만 알고있으면 충분합니다.
"참조 데이터 타입(Reference Data Type)"에는 문자열을 위한 String, 같은 유형의 데이터를 복수 개의 집합으로 관리할 수 있게 만들어주는 배열(Array), 사용자가 직접 여러 타입을 조합하여 새로운 타입을 정의할 수 있게 만들어주는 클래스(Class), 사용자가 열거한 값 중 하나의 값을 가질 수 있는 열거 타입(enum) 등이 있습니다.

3. 기본 데이터 타입. (Primitive Data Type)
기본 데이터 타입(Primitive Data Type)은 자바 언어에서 기본적으로 제공되는 데이터 타입입니다. 예약어(keyword)로 정의되어 있으며, 가장 기본적인 값의 연산을 위한 변수를 선언할 때 사용됩니다. 즉, "참 또는 거짓에 대한 판단", "수식(+,-,*,/ 등)에 의한 정수 값 계산", "문자(알파벳을 포함한 유니코드 형식의 문자) 처리", "실수 값 계산" 등을 위해 사용될 수 있습니다.
3.1 기본 데이터 타입(Primitive Data Type)의 종류.
자바에서 제공하는 기본 데이터 타입(Primitive Data Type)은 총 8개가 있으며, 다루고자 하는 값의 종류 및 크기에 따라 적절한 데이터 타입을 선택하면 됩니다.
boolean, byte, char, short, int, long, float, double
아래의 표는 각 데이터 타입에 대한 특징과 설명을 요약한 내용입니다.
| 데이터 타입 | 값의 분류 | 크기(Bytes) | 값의 종류 또는 범위 | 설명 |
|---|---|---|---|---|
| boolean | 논리(logic) | 1 | true, false | 참 또는 거짓을 다룰 때 사용. |
| char | 문자(character) | 2 | 0~65535 | 유니코드 문자(\u0000~\uFFFF)에 사용. |
| byte | 정수(integer) | 1 | -128~127 | 작은 범위의 정수 값 계산에 사용. |
| short | 정수(integer) | 2 | -32768~32767 | 중간 범위의 정수 값 계산에 사용. |
| int | 정수(integer) | 4 | -2147483648~2147483647 | 큰 범위의 정수 값 계산에 사용. |
| long | 정수(integer) | 8 | -231~231-1 | 아주 큰 범위의 정수 값 계산에 사용. |
| float | 실수(부동소수점, floating-point) | 4 | 1.4E-45~3.4028235E38 | 부동소수점 값 계산에 사용. |
| double | 실수(부동소수점, floating-point) | 8 | 4.9E-324 ~ 1.7976931348623157E308 | 큰 범위의 부동소수점 값 계산에 사용. |
3.2 기본 데이터 타입(Primitive Data Type) 변수.
[JAVA - 변수]에서 설명했듯이, 자바에서 변수를 만들기 위해서는 "데이터 타입" 뒤에 "변수 이름"을 적으면 됩니다. 그리고 대입(=) 연산자를 사용하여 값을 쓸 수 있습니다.
아래 몇 가지 예제 코드를 통해, 각 데이터 타입을 사용하여 변수를 만들고 사용하는 방법에 대해 확인할 수 있습니다.
// 정수 타입(byte) 변수 level에 정수 값 대입 및 출력.
byte level ;
level = 5 ;
System.out.println(level) ;
// 정수 타입(int) 변수 sum에 정수 값 대입 및 출력.
int sum = 43000 ;
System.out.println(sum) ;
// 문자 타입(char) 변수 capA에 문자 값 대입 및 출력.
char capA = 'A' ;
System.out.println(capA) ;
// 논리 타입(boolean) 변수 isError에 true 또는 false 값 대입 및 출력.
boolean isError = true ;
System.out.println(isError) ;
isError = false ;
System.out.println(isError) ;
// 실수 타입(float) 변수 pi에 부동소수점 값 대입 및 출력.
double pi = 3.14 ;
System.out.println(pi) ;
5
43000
A
true
false
3.14
3.3 어떤 데이터 타입을 사용해야 하는가?
앞에서 설명한 내용과 예제 코드를 통해 어느 정도 감을 잡으셨겠지만, 변수를 만들 때 어떤 데이터 타입을 사용할 것인지는 다루고자 하는 데이터의 유형에 따라 결정하면 됩니다. 예제 코드에서 볼 수 있듯이, 데이터 형식에 따라 사용할 수 있는 값의 형식(5, 'A', true, 3.14)이 확연하게 구분되죠.
그런데 정수 타입은, 같은 정수 값을 다루는 타입이더라도 byte, short, int, long으로 구분되어 있는 것을 확인할 수 있습니다. 이 네 가지의 정수 타입에는 무슨 차이가 있으며, 왜 이렇게 나뉘어져 있는 걸까요?
위에서 정리한 표를 보면 알겠지만, 이 타입들은 변수가 메모리에서 차지하는 크기가 다릅니다. 타입에 따라 메모리에 할당되는 변수의 Byte 수가 다르기 때문에 변수가 담을 수 있는 값의 범위도 달라집니다.

이처럼, 같은 정수 타입이지만 다른 크기의 데이터 타입이 여러 개 존재하는 이유는 프로그램에서 메모리를 효율적으로 사용할 수 있게 만들기 위함입니다.
예를 들어, 우리 나라 국민의 나이를 관리하는 프로그램을 작성한다고 가정해보죠. 지금까지 우리나라에서 127세를 넘게 산 사람은 없기 때문에 0~127 까지의 숫자만 저장할 수 있으면 됩니다. 이 값은 1 Byte(-128~127)에 저장할 수 있으므로, 나이를 관리하는 변수는 byte 타입으로 처리가 가능합니다. 우리나라 인구를 대략 5000만으로 잡았을 때, 약 50MBytes(50,000,000 x 1) 정도가 필요하죠.
그런데 나이 변수를 byte가 아닌 int로 지정하면 어떻게 될까요? int 타입은 byte보다 훨씬 큰 범위의 값을 저장할 수 있으니 프로그램 실행 과정에서는 어떠한 문제도 발생하지 않겠지만, 변수의 크기가 4 Bytes로 늘어나므로 전체 사용 메모리의 크기도 4배 늘어나게 됩니다. byte를 사용할 때보다 4배나 많은 200MBytes(50,000,000 x 4)의 메모리가 사용되겠죠.
완벽하게 동일한 데이터를 저장함에도, 어떤 데이터 타입을 사용하는지에 따라 4배나 많은 메모리를 사용하게 되었네요. 같은 정수 타입이라도 어떤 타입을 사용할 것인지는 조금 신중하게 선택해야 할 것 같습니다.
하지만 일반적인 경우에서, 네 가지 정수 타입 중 어떤 것을 사용할 것인지에 대해 너무 지나치게 고민할 필요는 없습니다. 위 예제는 조금 극단적인 경우를 가정했기 때문에 차이가 커보이지만, 대부분의 경우 저렇게 많은 데이터를 한꺼번에 변수로 만들어서 사용하는 경우는 거의 없기 때문이죠. 그리고 작은 정수 값을 예측하고 byte 타입을 사용했다가, 나중에 byte 범위(-128~127)를 넘어서는 값이 사용되는 경우, 에러가 발생하거나 완전히 잘못된 결과를 계산하게 될지도 모릅니다. (의료기술의 발달로 사람의 수명이 128세 이상이 된다면, 나이를 저장하는 변수에 제대로 된 값이 저장될까요? "byte age = 128;"의 실행 결과를 확인해보세요.)
일단, 정수 값을 다룰 때는 기본적으로 int 타입을 사용하면 됩니다. 만약 더 큰 범위의 값을 다뤄야 하면 long, 더 작은 범위의 값이 확실한 경우에는 short 또는 byte를 사용하면 됩니다.
그리고 정수 타입과 같이, 값의 범위에 따른 타입 선택은 float와 double 간의 관계에도 그대로 적용됩니다.
그 외 오직 참과 거짓, 즉 true 또는 false 중 하나의 값이 필요한 경우는 boolean, 문자 'A', 'B' 등과 같이 문자 단위의 처리가 필요한 경우는 char 타입을 사용하면 됩니다.
아래 코드에서, 데이터 타입에 따른 변수 사용 방법을 확인할 수 있는데요. 눈으로만 보지 말고, 코드를 직접 실행해보고, 결과를 직접 확인해 보시기 바랍니다. (뭔가 생소한 내용이 있다면, 상상하고, 찾아보고, 질문글 남겨주세요.)
// boolean 타입 변수 isGood에 true 값 대입 및 출력.
boolean isGood = true ;
System.out.println(isGood) ;
// char 타입 변수 rating에 문자 값 대입 및 출력.
char rating = 'S' ;
System.out.println(rating) ;
// byte 타입 변수 volume에 정수 값 대입 및 출력.
byte volume = 10 ;
System.out.println(volume) ;
// short 타입 변수 kor, math, eng 정수 값 대입 및 출력.
short kor = 100, math = 90, eng = 80 ;
System.out.println(kor + math + eng) ;
// int 타입 변수 febSalary, marSalary에 정수 값 대입 및 출력.
int febSalary = 10000000 ;
int marSalary = 11000000 ;
System.out.println(febSalary + marSalary) ;
// long 타입 변수 population에 정수 값 대입 및 출력.
long worldPopulation = 7000000000L ;
long korPopulation = 50000000L ;
System.out.println(worldPopulation - korPopulation) ;
// float 타입 변수 leftEyeVision, rightEyeVision에 실수 값 대입 및 출력.
float leftEyeVision = 1.5f, rightEyeVision = 1.2f ;
System.out.println("LEFT : " + leftEyeVision + ", RIGHT : " + rightEyeVision) ;
// double 타입 변수 lottoProbability에 실수 값 대입 및 출력.
double lottoProbability = 1d / 8145060d ;
System.out.println(lottoProbability) ;
true
S
10
270
21000000
6950000000
LEFT : 1.5, RIGHT : 1.2
1.2277380399898834E-7
4. 참조 데이터 타입. (Reference Data Type)
자바에서, 앞서 소개한 기본 데이터 타입(Primitive Data Type)이 아닌 모든 데이터 타입은 참조 데이터 타입(Reference Data Type)에 속합니다. (앞에서도 잠시 언급했듯이, 자바에서 "참조 데이터 타입"은 "기본이 아닌 데이터 타입(Non-primitive Data Type)"과 같은 의미로 사용됩니다.)
문자열(String), 배열(Array), 클래스(Class), 열거 타입(enum) 등이 참조 데이터 타입(Reference Data Type)에 해당하는데요. 이러한 참조 데이터 타입(Reference Data Type)들이 어떤 특징을 가지고 있기에 기본 데이터 타입(Primitive Data Type)과 구분되는 것일까요? 사용되는 값의 형식이 다른 걸까요? 아니면 차지하는 메모리의 크기가 다르기 때문일까요? 아니면 예약어(keyword)로 제공되지 않고 사용자가 그 타입 이름을 정할 수 있기 때문일까요?
네. 모두 맞습니다. 100% 정확히 일치하지는 않지만, 참조 데이터 타입(Reference Data Type)이 기본 데이터 타입(Primitive Data Type)과 구분되는 특징으로는 어느 정도 맞는 얘기입니다.
조금 더 구체적으로, 아래와 같이 정리할 수 있겠네요.
- 기본 데이터 타입(Primitive Data Type)은 예약어(keyword)로 제공되지만, 참조 데이터 타입(Reference Data Type)은 사용자에 의해 결정됩니다.
- 기본 데이터 타입(Primitive Data Type)은 사용되는 값의 형식이 자바 언어에 의해 이미 결정되어 있지만, 참조 데이터 타입(Reference Data Type)은 기본 데이터 타입의 조합(Class) 또는 집합(Array)으로 만들어집니다.
- 기본 데이터 타입(Primitive Data Type)은 타입에 따라 다른 크기를 가지지만, 참조 데이터 타입은(Reference Data Type)은 모두 동일한 크기를 가집니다.
- 기본 데이터 타입(Primitive Data Type) 변수는 대입되는 값(value)을 가지지만, 참조 데이터 타입(Reference Data Type)은 참조(reference)를 가집니다.
정리한 내용이 무슨 의미인지 이해가 되나요? 잘 이해가 안되시죠? 특히, 3번과 4번은 더욱 이해하기가 힘들거라 생각합니다. 하지만 지금 당장 이해되지 않는다고 당황하지 마세요. 잘못된 것은 하나도 없습니다.
4.1 참조 데이터 타입(Reference Data Type) 맛보기.
참조 데이터 타입(Reference Data Type)은 모두 동일한 크기를 가진다.
참조 데이터 타입(Refenence Data Type)은 참조(Reference)를 가진다.
이 내용이 참조 데이터 타입(Reference Data Type)을 이해하는데 필요한 핵심 내용입니다. 사실 이 두 문장을 완벽히 이해하면 더 이상 자바 초보개발자는 아니라고 생각합니다. 전후 관계를 조금 더 다듬어보자면, 참조 데이터 타입(Reference Data Type)은 참조(Reference)를 가지며, 그래서 참조 데이터 타입(Reference Data Type)은 동일한 크기를 가질 수 밖에 없습니다.
음.. 제대로된 설명도 없이, 자꾸 "참조(Reference)"라는 단어만 반복해서 언급하고 있네요. 다음 글에서, 기본 데이터 타입(Primitive Data Type) 변수가 데이터를 관리하는 구조와 참조 데이터 타입(Reference Data Type)이 데이터를 관리하는 구조를 비교해보고, 참조 데이터 타입(Reference Data Type)이 가지는 특징을 다시 한번 정리해보도록 하겠습니다.
아래 코드는 각 참조 데이터 타입 별 예제를 정리한 코드입니다. 각 코드의 의미를 지금 당장 이해하지 않아도 됩니다. 그냥 "저런 형태로 사용하는구나"라는 정도로만 이해하시면 충분합니다.
// 문자열 타입 변수 name에 값 대입 및 출력.
String name = "ppotta" ;
System.out.println(name) ;
// 정수 배열([]) 타입 변수 scores에 값 대입 및 출력.
int scores[] = { 100, 90, 80 } ;
int sum = scores[0] + scores[1] + scores[2] ;
System.out.println(scores[0] + " + " + scores[1] + " + " + scores[2] + " = " + sum) ;
// 클래스 Dog 정의 및 사용 예제.
class Dog {
private int legCount = 4 ;
private String voice = "WAL!" ;
public void speak() {
System.out.println(voice) ;
}
public void describe() {
System.out.println("A dog has " + legCount + " legs.") ;
}
}
Dog dog = new Dog() ;
dog.describe() ;
dog.speak() ;
// 열러 타입 Language 정의 및 사용 예제.
enum Language {
JAVA,
C,
JAVASCRIPT
}
Language favoriteLang = Language.JAVA ;
System.out.println(favoriteLang) ;
ppotta
100 + 90 + 80 = 270
A dog has 4 legs.
WAL!
JAVA
5. 참고.
*
.END.
'JAVA > JAVA - 변수,상수' 카테고리의 다른 글
| JAVA - 변수. (Java Variable) (0) | 2021.02.27 |
|---|