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으로 간주하게 된다.