프로그래밍 언어에서 변수를 다루는 방식은 데이터 타입에 따라 다양하게 변한다. 자바에서는 데이터 타입을 크게 원시 타입(Primitive Type)과 참조 타입(Reference Type) 두 가지로 구분할 수 있다. 이 둘은 프로그래밍 언어의 핵심 요소로, 데이터의 특징과 사용 방식에서 차이를 보인다.
boolean), 문자형(char), 정수형(byte, short, int, long) 실수형(float, double)이 있다.flase boolean myBoolean = true;
char myChar = 'A';
정수형의 기본 자료형은 int이다.
byte myByte = 10;
short myShort = 1000;
int myInt = 100000;
long myLong = 1000000000; // 에러 발생
long myLong = 1000000000L;
/* long타입의 리터럴에는 접미사 L 또는 l 를 붙여야하는데,
이를 표기하지 않으면 int형으로 간주하게 되어 에러가 발생한다. */
실수형의 기본 자료형은 double이다.
float myFloat = 3.14; // 에러 발생
float myFloat = 3.14f;
/* float타입의 리터럴에는 접미사 F 또는 f 를 붙여야하는데,
이를 표기하지 않으면 double형으로 간주하게 되어 에러가 발생한다. */
double myDouble = 3.141592;
초기화
원시 타입 변수는 선언한 후 반드시 초기화되어야 한다. 초기화하지 않은 변수를 사용하려고 하면 컴파일 오류가 발생한다. 초기화는 변수에 적절한 값을 할당하는 것을 의미하며, 초기화하지 않으면 해당 원시 타입의 기본값이 자동으로 할당된다.
데이터 표현 범위 주의
각 원시 타입은 표현 가능한 값의 범위가 다르다. 예를 들어 byte 타입은 -128부터 127까지의 값을 표현할 수 있지만, 이 범위를 벗어나는 값이 할당되면 오버플로우(Overflow)가 발생할 수 있다. 데이터의 범위를 고려하여 적절한 원시 타입을 선택하고 사용해야 한다.
정밀도 손실
실수형 원시 타입인 float와 double은 부동 소수점 형식을 사용하며, 이로 인해 정밀도 손실이 발생할 수 있다. 특히 긴 계산을 수행할 때 정밀한 결과가 필요한 경우, 부동 소수점 타입 사용 시 주의가 필요하다.
객체와 혼용 불가
원시 타입은 객체가 아니기 때문에, 객체와 혼용할 수 없다. 예를 들어 원시 타입 변수에는 메소드를 호출할 수 없으며, null 값으로 초기화할 수 없다. 이런 경우에는 참조 타입을 사용해야 한다.
박싱과 언박싱
원시 타입을 참조 타입으로 변환하거나, 참조 타입을 원시 타입으로 변환하는 작업은 박싱(Boxing)과 언박싱(Unboxing)이라고 불린다. 이 작업은 자동으로 처리되기도 하지만, 성능 저하를 유발할 수 있으므로 반드시 필요한 경우에만 사용해야 한다.
배열과 제네릭 컬렉션
원시 타입을 배열이나 제네릭 컬렉션에 저장할 경우, 타입 안정성(type safety)이 보장되지 않는다. 따라서 객체를 다루는 경우에는 객체 래퍼 클래스(Wrapper Class)를 사용하거나, 자바 제네릭(Java Generic)를 활용하여 타입 안정성을 유지하는 것이 좋다.
클래스, 인터페이스, 배열 등이 참조 타입이다.null 값을 가진다.// String은 참조 타입으로 문자열을 나타내는 클래스이다.
String myString = "Hello, Java!";
클래스(Class)
사용자가 정의한 데이터 타입을 나타내며 객체의 속성(멤버 변수)과 동작(메서드)를 정의한다.
인터페이스(Interface)
클래스가 구현해야 하는 메서드 목록을 정의한다. 다중 상속을 지원하기 위한 중요한 개념이다.
배열(Array)
동일한 타입의 데이터를 여러 개 저장하는 자료 구조이다.
열거형(Enum)
몇 가지 고정된 값 중 하나를 나타내는 데이터 타입이다. 열거형은 보통 연관된 상수 값을 그룹화할 때 사용된다.
제네릭(Generic)
클래스나 메서드를 작성할 때 타입을 파라미터화할 수 있는 기능을 제공한다. 타입 안정성을 높이고 재사용성을 높이는 데 사용된다.
Null 체크
참조 타입 변수는 null일 수 있으므로 사용 전에 항상 null 여부를 체크해야 한다.
메모리 관리
참조 타입은 힙 메모리에 저장되므로 메모리 누수를 방지하기 위해 더 이상 필요하지 않는 객체에 대한 참조를 해제해야 한다.
객체 생성
클래스의 인스턴스를 생성할 때 new 키워드를 사용하며, 생성자를 호출하여 객체를 초기화한다.
단순한 데이터 값을 저장
원시 타입 변수는 해당 데이터의 값을 직접 저장한다. 복잡한 구조를 가지지 않으며, 그 자체로 값 하나를 나타낸다.
스택 메모리에 저장
원시 타입 변수는 스택(Stack) 메모리에 직접 값이 저장된다. 스택 메모리는 데이터를 효율적으로 저장하고 관리하는 데 사용되며, 변수의 범위(scope)와 함께 관리된다.
기본형 타입
원시 타입은 다음과 같은 기본형(primitive type)으로 나뉜다.
true 또는 false 값을 표현자동 초기화
원시 타입 변수는 선언만 하고 초기화하지 않으면 해당 데이터 타입에 따른 기본 값으로 자동 초기화된다. 이는 변수를 사용하기 전에 명시적으로 초기화해야 할 필요가 없다는 장점을 가진다.
메모리 사용량이 적음
원시 타입 변수는 각각 고정된 크기를 가지므로 메모리 사용량이 상대적으로 적다. 이는 대량의 데이터를 다룰 때 효율적이다.
빠른 연산
원시 타입은 별도의 연산을 거치지 않고 직접 연산이 가능하기 때문에 연산이 빠르다.
객체가 아닌 값
원시 타입은 객체가 아닌 값(value)을 다룬다. 이로 인해 객체 지향 프로그래밍 언어인 자바에서도 기본적인 연산과 데이터 저장에 효율적으로 사용된다.
메모리 동적 할당
참조 타입의 데이터는 스택 메모리가 아닌 힙(heap) 메모리에 저장된다. 이는 데이터 크기가 동적으로 변할 수 있음을 의미하며, 메모리의 효율적인 활용을 가능하게 한다.
객체 지향 프로그래밍
참조 타입은 객체 지향 프로그래밍(OOP)의 핵심 원칙을 구현하는 데 사용된다. 클래스를 정의하고 인스턴스(객체)를 생성하여 데이터와 동작을 함께 캡슐화할 수 있다.
Null 값 지원
참조 타입 변수는 참조할 객체가 없는 경우 null 값을 가질 수 있다. 이는 객체의 존재 유무를 나타내는데 유용하게 사용된다.
값 vs 주소
원시 타입은 값을 직접 저장하고, 참조 타입은 값이 저장된 메모리 주소를 가리킨다.
크기
원시 타입은 크기가 정해져 있으며, 참조 타입은 객체의 크기가 변한다.
메모리 영역
원시 타입은 스택(Stack)에 저장되고, 참조 타입은 스택에는 주소가, 객체는 힙(Heap) 메모리에 저장된다.
null 값
원시 타입은 항상 값을 가지며 초기화된다. 참조 타입은 초기화되지 않으면 null 값을 가진다.
사용
원시 타입은 단순한 데이터 값을 저장하고 연산할 때 사용되며, 참조 타입은 객체를 생성하고 그 내부의 데이터와 메서드에 접근할 때 사용된다.
원시 타입은 값 자체를 저장하므로 작은 메모리 공간을 사용하며 빠른 연산이 가능하다. 반면에 참조형 변수는 실제 값이 아니라 객체나 배열의 메모리 주소를 저장하며, 해당 주소를 통해 실제 데이터에 접근한다.
원시 타입과 참조 타입은 자바 프로그래밍에서 기본적인 개념 중 하나로, 개발자가 변수를 선언하고 데이터를 다루는 데 있어서 핵심적인 역할을 한다.
빠른 연산을 위해 사용되는 원시 타입과 객체 지향 프로그래밍에서 다양한 종류의 객체를 효율적으로 다룰 수 있도록 해주는 참조 타입의 특징을 이해하고 적절히 활용하는 것은 코드의 효율성과 가독성을 높이는데 도움이 될 것이다.