IT 공부 독서 정리/Java의 정석
자바의 정석 Chapter 2.2 - 변수의 타입 (Data Type)
방탄승
2025. 1. 31. 19:05
앞 챕터에서는 자바 개발뿐 아니라 프로그램 개발을 할 때, 사용하는 저장공간인 변수에 대해 알아보았다.
이번 챕터에서는 이 변수(저장공간)을 선언하는데, 필요한 변수의 타입에 대해 알아보고자 한다.
우선 이해를 위해 인간과 컴퓨터간의 테이터를 인식하는 차이를 생각해 본다.
1. 변수 타입의 이해
🧠 인간과 💻 컴퓨터의 데이터 인식 차이
1. 인간은 문맥을 이해하고 데이터를 유연하게 구분한다.
인간은 상황에 따라 같은 단어라도 다르게 받아들인다.
"100"이란 숫자에 대해서..
누군가 "100을 세보세요!" 하면 → 수량으로 이해하고 1, 2, 3… 새어나간다."
이 상품은 100원입니다." 하면 → 돈으로 받아들이고 가격 개념을 떠올린다.
"오늘 기온이 100도야!" 하면 → 온도로 해석하고 정보를 처리한다.
같은 데이터에 대해서 작성된 문장의 앞뒤 문맥을 통해 정보를 파악하고 그에 맞는 데이터 처리를 한다.
2. 그러나, 컴퓨터는 데이터를 스스로 해석하지 못한다.
컴퓨터는 기본적으로 0 또는 1 두 가지의 값으로만 데이터를 처리하는 장치이다.
따라서, 컴퓨터는 문맥을 이해하지 못하고, 오직 미리 정해진 규칙에 따라서만 데이터를 처리할 수 있다.
그래서 우리가 개발할 때 각 데이터의 성격(=자료형, 데이터 타입)을 지정하도록 체계를 만들게 되었다.
아래 예시와 같이 원하는 값의 특성을 고려하여 가장 알맞은 데이터 타입을 설정하면 된다.
Ex)
데이터 타입 값 정수 (int) 1, 2, 100 실수 (float/double) 3.14, 0.1 문자열 "hello", "100" 블리언(boolean) true, false 배열/리스트 같은 타입의 여러 개의 데이터를 저장 객체 서로 다른 타입의 데이터들을 하나로 묶어 관리
2. 기본형과 참조형
- 자료형은 크게 '기본형'과 '참조형' 두 가지로 구분한다.
- 기본형은 값(data)을 저장하며, 참조형의 어떤 값의 주소(memory address)를 저장한다.
- 자바는 C언어와 달리 참조형 변수 간의 연산이 불가능하다.
- 실제 연산에 사용되는 변수는 모두 기본형이다.
- 참조형 변수는 클래스 이름이 참조변수의 타입이 된다.
기본형 변수 | 참조형 변수 | 기본형 선언 | 참조형 선언 |
논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double) |
기본형을 제외한 모든 타입 | int number; double pi; 등등 |
클래스 이름 변수이름; Date date = new Date(); |
- 기본형 선언은 간단하게 기본형 타입 변수이름; 으로 선언하면 된다.
- 참조형 선언의 경우에는 new 키워드를 사용하여 선언을 하게 된다.
- new 키워드의 역할은 객체를 생성하여 주소값을 얻는 역할을 한다.
- 이 키워드를 통해 주소가 date라는 변수에 저장이 되며, 이 순간부터 date변수를 사용할 수 있게 된다.
2.1 기본형(Primitive Type)
- 기본형에는 크게 8가지 타입으로 구분된다.
- 8개의 타입은 분류적으로 논리형, 문자형, 정수형, 실수형으로 나뉜다.
분류 | 타입 |
논리형 | boolean |
true/false 둘 중 하나를 값으로 갖으며, 조건식과 논리적 계산에 사용되는 타입 | |
문자형 | char |
문자를 저장하는데 사용되며, 변수 하나에 문자 하나만 저장 가능함. | |
정수형 | byte, short, int, long |
주로 int가 사용됨. byte는 이진데이터를 처리하는데 사용, short는 c언어 호환을 위해 추가 됨. | |
실수형 | float, double |
실수를 저장하는데 사용되며, 주로 double를 사용함. |
- char형의 경우 문자를 결국 내부적으로는 정수(유니코드)로 저장하기에, 정수형과 별반 다르지 않음.
- 따라서, 정수형 또는 실수형과의 연산이 가능함.
- 다만, boolean의 경우 다른 기본형과의 연산이 불가능
- 따라서, boolean을 제외한 모든 기본형들은 기본형들 간의 연산이 가능
- 각 분류별 타입의 경우, 각 분류별 저장할 수 있는 데이터의 저장 공간으로 구분됨.
- 정수형의 경우 코딩에서 가장 많이 사용되므로, 타입을 4가지까지 제공됨.
- 일반적으로 int를 가장 많이 사용 (CPU 처리에 가장 효율적인 타입)
- 변수 타입은 데이터의 종류에 따라 1차로 구분하고, 데이터의 크기에 따라 2차로 분류한다.
- 데이터 타입의 선정은 그 프로그램의 메모리 효율과 관련이 있어, 첫 설계가 매우 중요하다.
2.2.1 상수(constant)
- '상수(constant)'는 변수와 마찬가지로 값을 저장할 수 있는 공간이다.
- 다만, 차이는 상수의 경우 첫 선언 이후 값의 변경이 불가능한 공간을 의미한다.
- 상수 선언은 변수와 동일하며 단지 변수의 타입 앞에 'final'키워드를 붙여주면 된다.
- 상수의 이름은 모두 대문자로 작성하는 것이 관례이며, 여러 단어의 경우 '_'로 구분한다.
ex)
final int MAX_SPEED; // error, 선언과 동시에 초기화를 해줘야 한다.
final int MAX_VALUE = 100; // OK. 선언과 동시에 초기화를 하였다.
MAX_VALUE = 200; // error, 위에서 선언과 초기화를 했기에, 변경할 수 없음.
2.2.2 리터럴(literal)
- 12,124,3.14와 같이 항상 그 값을 의미하는 수들을 '상수'라고 한다.
- 위와 같은 값들이 흔히 우리가 사용하는 일상생활에서의 상수이다.
- 허나 이 상수라는 개념을 프로그래밍 언어에서는 한번 정의 후 변경할 수 없는 저장공간으로 사용한다.
- 따라서, 해당 값 자체를 의미하는 용어가 필요하게 되었고, 이것이 리터럴이라는 용어로 사용하게 되었다.
변수(variable) : 하나의 값을 저장하기 위한 공간
상수(constnat) : 값을 한 번만 저장할 수 있는 공간
리터럴(literal) : 그 자체로 값을 의미하는 것
2.2.3 상수가 필요한 이유
- 리터럴을 직접 쓰지 않고, 상수라는 개념을 도입한 이유는 무엇일까?
int triangleArea = (20 * 10) / 2; // 삼각형의 면적을 구하는 공식
int rectangleArea = 20 * 10; // 사각형의 면적을 구하는 공식
위 공식을 한번 살펴보게 되면, 삼각형과 사각형의 면적을 구하여 변수에 저장하고 있다.
다만, 위 공식에서의 높이와 폭의 값이 변경되었다고 한다면..
20과 10의 값을 변경해야 되며, 삼각형과 사각형의 공식에 있는 4개의 값을 각각 변경해야 한다.
이러한 공식의 복잡도가 높아진다면, 수정 시 번거로움과 실수가 발생하기 쉽다.
final int WIDTH = 20; // 푝
final int HEIGHT = 10; // 높이
int triangleArea = (WIDTH * HEIGHT) / 2; // 삼각형의 면적을 구하는 공식
int rectangleArea = WIDTH * HEIGHT; // 사각형의 면적을 구하는 공식
상수를 이용해서 기존의 코드를 위와 같이 변경해 보았다.
우선 이전 코드에 비해 면적을 구하는 공식의 가독성이 높아짐을 확인할 수 있다.
다른 값으로 계산이 필요할 때 위 final의 변수에 초기화 한 값만 다른 값으로 수정하면된다.
상수는 리터럴에 '의미 있는 이름'을 붙여서 코드의 이해와 수정을 쉽게 만든다는 장점이 있다.
2.2.4 리터럴의 타입과 접미사
- 변수에 타입이 존재하듯이 리터럴에도 타입이 있다.
- 변수의 타입은 저장될 값의 타입에 의해 결정된다.
- 따라서, 리터럴에도 당연히 타입이 존재한다.
- 정수형과 실수형에는 여러 변수 타입이 있으며, 각 타입에 맞는 리터럴 타입을 설정해야 한다.
- 리터럴은 기본적으로 타입에 해당하는 문자를 접미사에 붙여서 구분한다.
- 정수형의 경우 long타입에 'l' 또는 'L'을 붙이며, 접미사가 없으면 기본 int로 인식한다.
- short나 byte는 따로 리터럴이 없으며, 값 저장 시 int타입의 리터럴 타입을 적용
- 2/8/16 진수를 표현하기 위한 리터럴 타입도 존재
- 2진수는 '0b' / 8진수는 '0(숫자)' / 16진수는 '0x'를 붙여 사용.
- 실수형 리터럴에는 float는 f를 붙이고, double은 d를 붙여 사용.
- 다만 리터럴 타입을 작성하지 않으면 기본 double로 인식
- 리터럴 타입은 대소문자 구분하지 않는다.
- 다만, 가독성과 원활한 소통을 위해 대문자를 기본적으로 사용하는 것이 좋다.
- 리터럴에 소수점이나 10의 제곱을 나타내는 기호/접미사 f, F, d, D를 포함하면 실수형 리터럴로 간주
- 리터럴 타입은 저장될 변수의 타입과 일치해야 하는 것이 보통이다.
- 타입의 불일치에 대한 오륙가 있긴 하나, 변수와 같이 규칙이 철저하게 작성되지는 않았다.
- 다만, 타입이 달라도 저장범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용된다.
int i = 'A'; // OK. 문자'A'의 유니코드인 65가 변수 i에 저장
long l = 1234; // OK. int보다 long타입이 범위가 넓음
double d = 3.14f; // OK. float보다 double 타입 범위가 넓음
- 다만, 위와 반대되는 경우에는 에러가 발생한다.
- 따라서 웬만하면 범위에 맞는 리터럴 타입을 설정하는 것이 좋다.
2.2.5 문자 리터럴과 문자열 리터럴
- 'A'와 작은따옴표로 이루어진 것을 '문자 리터럴이라고 한다.
- "AB"와 같이 두 문자 이상을 표현하기 위해 큰 따옴표로 감싼 것을 문자열 리터럴이라고 한다.
- 하나의 문자를 사용할 땐 char / 두 개 이상의 문자를 표현할 땐 String를 사용.
- 또한 문자열 리터럴은 ""와 같이 아무것도 없는 blank를 허용하지만, 문자 리터럴은 허용하지 않는다.
String str = ""; // OK. 내용 없는 문자열
char ch = ''; // 에러. ''안에 반드시 하나의 문자 필요
char ch = ' '; // OK. 공백 문자(blank)로 변수 ch를 초기화
- 원래 String도 클래스이기에 new키워드를 사용해야 한다.
- 하짐나, 자주 사용하는 클래스이기에, 위와 같은 선언도 허용한다.
- 또한 문자열끼리의 연산자를 이용한 결합도 허용하고 있다.
String str = new String("JAVA"); // 이것이 정석
String name = "JA" + "VA"; // name은 "JAVA"
String str2 = name + "8.0"; // str2는 "JAVA 8.0"
String str3 = name + 8.0; // str3도 "JAVA 8.8"
- 위와 str3 변수와 같이 문자열과 다른 타입의 변수 간의 결합을 하게 되면 String으로 간주하게 된다.