Tiny Star

🪄Interview/✏️Study

[CS STUDY INTERVIEW] 3주차 - Primitive type(기본/원시타입)과 Reference type(참조타입)

청크 2024. 2. 26. 19:44

CS 스터디 3주차

 

자바에서는 데이터 타입을 두 가지 범주로 나눌 수 있다.

 

기본/원시 타입(Primitive type)과 참조타입 (Reference type)이 있는데 

기본/원시 타입(Primitive type)은 쉽게 말해 정수, 실수, 문자, 리터럴 등 실제 데이터 값이 저장되고

참조 타입(Reference type) 객체의 주소를 참조하는 타입으로 메모리의 주소 값을 통해 객체를 참조한다.


Primitive type (기본/원시 타입)

기본 데이터 타입은 자바에서 제공하는 내장된 데이터 타입으로, 간단한 값을 저장하는데 사용된다.

이 타입은 미리 정의되어 있고 변수에 직접 값을 저장한다.

종류 키워드 크기 기본값 표현 범위
논리형(Boolean Type) boolean 1byte false true or false
수형(Integer Type) byte 1byte 0 -128 ~ 127
short 1byte 0 - 32768 ~ 32767
int 4byte 0 -2147483648 ~ 2147483647( -21억 ~ + 21억)
long 8byte 0 -9223372036854775808 ~ 9223372036854775807(-100경 ~ + 100경)
실수형 (Floating Type) float 4byte 0.0 1.4E-45 ~ 3.4028235E38
double 8byte 0.0 4.9E-324 ~ 1.7976931348623157E308
문자형 (Character Type) char 2byte \u000 '\u0000' ~ 'uFFFF' (16비트 유니코드 문자 데이터)

 

 

1. 논리형(Boolean Type)

boolean isTrue = true;
boolean isFalse = flase;

참과 거짓을 저장하는 타입으로 주로 yes/no, on/off 등의 논리 구현에 주로 사용되며

true/false 두 가지의 값만 표현하므로 크기는 1byte로 가장 작으며 기본값은 false이다.

 

boolean의 실제 데이터 크기는 1bit면 충분 할 정도로 작은 크기지만 자바가 다루는 데이터의 최소 범위가 1byte이기 때문에

낭비적이지만 1byte를 사용한다.

 

2. 정수형(Integer Type)

int num = 10;

1) byte

가장 기본이 되는 데이터 타입으로 주로 이진데이터를 다루는데 사용된다.

 작은 범위의 값을 표현할 때 사용하므로 메모리 사용량이 적다.

 

2) short

byte보다 큰 범위의 값을 표현할 때 사용하게 된다.

C언어와의 호환을 위해 사용되는 타입이지만 주로 int나 long타입을 더 많이 사용하기 때문에 잘 사용되지 않는 타입이다.

 

3) int

자바에서 정수 연산을 하기 위한 기본 타입으로 정수형 데이터를 사용하게 되면 JVM에서 기본적으로 int형 타입으로 데이터를 인식한다.

JVM의 피연산자 스택이 피연산자를 4byte 단위로 저장하기 때문에 int형보다 작은 자료형의 값을 계산할 시에

int형으로 형변환이 되어 연산이 수행된다.

 

주로 정수의 연산이나 배열의 인덱스 등 다양한 상황에서 사용을 하고,

-21억~21억까지의 값을 표현할 수 있기 때문에 대부분의 상황에서는 충분한 범위를 제공한다.

 

 4) long

수치가 큰 데이터를 다루는 프로그램(은행 등)에서 주로 사용하는 타입으로

long타입의 변수를 초기화 할 때는 정수 값  뒤에 'l' 또는 'L' (알파벳 L의 소문자 또는 대문자)을 붙여서

long타입의 정수 데이터임을 알려주어야 한다.

long l = 2147483648; // 컴파일 에러 발생
long l = 2147483648L; //long type이라는 것을 표시

만일 정수값이 int의 저장범위를 넘는 정수에서 L이 붙지 않는다면 컴파일 에러가 발생하게 된다.

 

3. 실수형(Floating Type) 

double pi = 3.14;

실수형 타입은 부동 소수점 숫자를 표현할 때 사용된다.

여기서 부동 소수점이란 소수점 이하의 위치가 고정되어 있지 않고, 소수점의 위치가 움직일 수 있는 숫자를 의미한다.

 

정수형 타입과 달리 소수점 이하의 값을 저장하고 처리하는데,부동 소수점 연산의 특성 상 정확한 값의 비교가 어렵기 때문에 사용 시 주의가 필요하다.

 

정확한 계산이 필요하다면 double, 메모리를 절약해야 한다면 float 타입을 사용하면 된다.

 

1) float

소수점 이하 7자리까지 제공하며, 기본형 데이터 타입이 double이기 때문에 float 타입을 사용할 때도

long타입과 같이 실수 값 뒤에 'f' 또는 'F'를 붙여서 데이터 타입을 알려야한다.

float f = 1234.567;  // 컴파일 에러가 발생
float f = 1234.567F; // float type이라는 것을 표시

2) double

소수점 이하 15자리까지 제공하며, 자바의 실수형 데이터 타입에서는 double형 데이터 타입이 기본 타입이다.

 

4. 문자형(Character Type) 

char grade = 'A';

주로 문자열을 처리할 때 사용되는 데이터 타입으로 자바에서는 char라는 이름으로 제공하며

char타입은 2byte를 사용하여 유니코드 정수형태로 저장한다.

 

char타입은 자바에서 유일하게 제공되는 unsigned 형태로 맨 앞 비트를 음수/양수 형식으로 사용하지 않으며

문자 하나만을 저장하는 데 사용하고 문자열을 다루는데에는 String 클래스가 주로 사용된다.

 

문자의 리터럴

char ch1 = 'A'; // 문자 리터럴
char ch2 = '\u0041'; // 유니코드 리터럴, 위와 같은 결과

작은 따옴표('')로 둘러쌓인 하나의 문자를 나타내고 간단한 문자를 직접 표현할 때 사용된다.

예를들면 'A', 'B', 'C' 와 같이 특정 문자를 표현할 때 사용되거나 유니코드 값을 사용하여 특정 문자를 표현할 수도 있다.

('\U0041' = 'A')

 

Escape 시퀀스

또한 char 타입에서는 역슬래시와 특정 문자를 조합하여 이스케이프 시퀀스를 사용할 수 있는데

이는 문자열 안에서 특수한 의미를 가진 문자를 나타내기 위해서 사용한다.

System.out.println("Hello\nWorld"); // 줄 바꿈
System.out.println("Hello\tWorld"); // 탭
System.out.println("Hello\rWorld"); // 캐리지 리턴
System.out.println("C:\\Users\\User\\Desktop"); //역슬래시
System.out.println("It's a beautiful day"); // 작은 따옴표
System.out.println("She said, \"Hello!\""); // 큰 따옴표
System.out.println("She said, \"Hello!\""); // 백스페이스
System.out.println("Page 1\fPage 2"); //폼 피드
System.out.println("Hello\0World"); // 문자열의 끝

- \n : 줄 바꿈 (개행)

- \t : 탭

- \r :  캐리지리턴

- \\ : 역슬래시

- \' : 작은 따옴표(단일 인용부호)

- \" :  큰 따옴표(이중 인용부호)

- \b : 백스페이스

- \f : 폼 피드 (새 페이지 시작)


Reference type (참조 타입)

쉽게 설명하면 자바의 기본(원시)타입을 제외한 모든 타입들은 참조 타입에 해당이 된다.

이는 자바에서 제일 최상의 조상인 java.lang.Object 클래스를 상속하는 모든 클래스들을 포함한다는 의미이기도 하다.

 

참조 데이터 타입은 객체를 다루는데 사용되며, 객체 지향 프로그래밍에서 매우 중요한 개념이다.

이 타입들은 객체를 가리키는 참조값을 저장하는 데이터 타입으로 자바의 문자열이나 배열, 열거형, 클래스, 인터페이스 등이 해당된다.

 

실제 객체는 힙(Heap) 메모리 영역에 저장되고, 변수에는 해당 객체의 참조값이 저장된다.

참조 타입의 변수는 스택(Stack) 영역에 객체의 주소를 저장하며, 이 주소를 사용하여 객체의 메서드와 속성에 접근할 수 있다.

참조 타입에서는 빈 객체를 나타내는 Null이 존재하는데

Null은 문법상으로는 에러가 없지만, 실행 시에는 런타임 에러인 NullPointException이 발생할 수 있다.

이를 방지하기 위해서는 변수에 값이 할당을 해야하지만 항상 필수적인 것은 아니니 유의해야한다.

 

1) 클래스(Class)

// 클래스 정의
class Person {
    String name;
    int age;
}

// 클래스 인스턴스 생성
Person person1 = new Person();
person1.name = "John";
person1.age = 30;

클래스는 객체를 생성하기 위한 설계도로, 관련된 속성(필드)이나 기능(메서드)를 포함하고 있다.

- 객체 생성 : 클래스를 기반으로 여러 개의 객체 생성이 가능하며 실제 데이터를 담고 있는 객체를 생성할 때 사용된다.

- 상속 : 클래스는 타 클래스로부터 상속을 받아 새로운 클래스 정의가 가능하다.

- 캡슐화 : 관련된 데이터와 기능을 하나로 묶어 캡슐화가 가능하다.

 

2) 인터페이스(Interface)

interface Animal {
    void sound();
}

// 인터페이스를 구현한 클래스의 인스턴스
class Dog implements Animal {
    public void sound() {
        System.out.println("Woof!");
    }
}

Animal animal = new Dog();

 구현부가 없는 추상메서드의 집합으로 구현체에게 해당 메서드를 반드시 구현하도록 강제한다.

원래 클래스는 한 개의 클래스만 상속받을 수 있지만 인터페이스는 여러 개 구현이 가능하며

특정 기능을 정의하기 위한 틀로 사용된다.

 

3) 배열(Array)

int[] numbers = {1, 2, 3, 4, 5}; // 1차원 배열
int[][] matrix = {{1, 2}, {3, 4}}; // 2차원 배열

같은 데이터 타입의 값을 여러개 저장할 수 있는 구조로 처음 생성 시 지정된 크기는 변경이 불가하며배열은 각 요소에 대한 인덱스를 가지며 그 인덱스를 통해서 해당 요소에 접근한다.

 

배열 안에 또다른 배열이 포함되어 있는 다차원 배열 생성이 가능하다.

4) 문자열(String)

String str = "Hello, World!";
System.out.println(str.length()); // 문자열 길이
System.out.println(str.charAt(0)); // 첫 번째 문자
System.out.println(str.substring(0, 5)); // 문자열 자르기

문자의 시퀀스로 자바에서는 문자열을 위한 String 클래스를 제공한다.

이 클래스는 참조형에 속하지만 기본적인 사용은 기본형 타입처럼 사용되기 때문에 조금 특별하다고 할 수 있다.

 

한번 생성되면 변경이 불가한 불변의 객체로 새로운 문자열을 생성할 때마다 메모리에 새로운 공간이 할당되며

문자열 연산은 또 다른 새로운 문자열을 생성하므로 자주 발생하는 연산인 경우 메모리 성능 저하를 발생시킬 수 있다.

 

값의 비교를 위해서는 == 연산자가 아닌 .equals() 메서드를 사용하여 객체 간의 비교가 가능하다.

 

5) 열거형(Enum)

enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

Day today = Day.MONDAY;
System.out.println("Today is " + today);

서로 연관된 상수들의 집합으로 미리 정의된 상수 값 중 하나를 가질 수 있다.

열거형의 경우 컴파일 시점에 타입 검사가 가능하여 타입 안전성을 제공하며

메서드와 필드를 포함할 수 있기 때문에 더 복잡한 상수값의 표현이 가능하다.


 정적 메모리 스택(Stack)과 동적 메모리 (Heap)

정적 메모리 - 스택(Stack) 영역

스택 영역에는 기본 타입 변수가 할당되고 변수의 실제 값들이 저장된다.

참조 타입의 변수들은 이 스택 영역에서 힙 영역에 생성된 객체들의 주소 값을 저장하고 보관한 뒤

객체 안의 메서드 작업이 종료되면 할당되었던 메모리 공간들은 반환되어 비워지게 된다.

 

동적 메모리 - 힙(Heap) 영역

힙 영역에는 객체와 배열이 생성되고 참조타입들이 이 객체들의 주소를 스택 영역에 저장한다.

기본타입 변수들과 다르게 크기가 정해져있지 않아 프로그램 실행 시 메모리에 동적으로 할당된다.

 

만약 참조하는 변수가 없다면 가바지 컬렉터가 돌면서 객체를 제거하여 메모리를 해제시킨다.


Primitive type(기본/원시타입)과 Reference type(참조타입)

두 타입의 차이점은 크게 두 가지가 있다.

 

1. Null 포함 가능 여부

int num = null; //불가능 (값을 담은 변수)
Integer num = null; //가능 (객체의 주소값을 담은 변수)

기본 타입 변수는 해당 타입의 값을 직접 저장하기 때문에 Null값이 존재할 수 없지만

참조 타입은 객체의 주소를 저장하는 변수이기 때문에 Null값을 가질 수가 있다.

 

2. 제너릭 타입에서 사용 여부

ArrayList<int> //허용되지 않는 기본형 타입
ArrayList<String> //참조타입은 사용이 가능

제너릭 클래스나 메서드를 정의할 때 타입 매개변수로는 기본 타입을 사용할 수 없지만

참조 타입은 제너릭 클래스나 메서드에 타입 메개변수로 사용이 가능하다.

 

원시타입에서 제네릭 타입으로의 변환에 대한 제약은 여러가지가 있는 다음과 같은 이유로 발생한다.

 

타입 안전성

제네릭 타입 안전성을 보장하기 위해 도입되었다.원시타입은 제네릭에서 타입안전성을 보장할 수 없는 경우가 있어 제네릭 타입으로의 변환을 허용하지 않는 것이다.

 

예를 들어, 제네릭을 사용하여 리스트에 문자열만 저장할 수 있다고 가정해본다면,

만약 원시타입으로 변환한다면, 그 리스트에는 문자열이 아닌 다른 타입의 객체가 들어갈 수 있기 때문에 타입 안전성이 보장되지 않게 된다.

 

컴파일 시 체크

제네릭을 사용하면 컴파일러가 타입 불일치를 미리 감지하여 컴파일 시에 에러를 발생시키지만

원시타입은 컴파일 시에 타입 체크가 이뤄지지 않기 때문에 이러한 체크를 보장할 수 없기 때문에 제약사항이 생긴다.

 

코드 가독성과 유지보수성

제네릭을 사용하면 타입 파라미터를 통해 메서드나 클래스의 의도가 명확히 드러나기 때문에 코드의 가독성과 유지보수성이 향상된다는 장점이 있다.

반면에 원시타입은 타입 정보가 손실되어 코드의 가독성이 떨어지고, 유지보수가 어려워질 수 있는 단점이 있다.

 

성능 향상

제네릭을 사용하면 컴파일러가 코드를 더 효율적으로 최적화할 수 있지만 반면에 원시타입은 이러한 최적화가 어려울 수 있다.

이러한 이유로 원시타입과 제네릭 타입은 서로 다른 특성을 가지고 있고, 
원시타입에서 제네릭 타입으로의 변환은 타입 안전성과 코드의 가독성 등을 보장하기 위해 제약이 설정되어 있기 때문에제네릭 타입에서 사용 여부의 차이점이 발생한다.

 

  Primitive Type Reference Type
장점 메모리의 효율적 사용
빠른 연산
객체 지향적인 기능 활용에 용이
유연한 데이터 구조
단점 객체 지향적인 기능의 제한
Null값 불가능
메모리 사용량의 증가
연산속도 감소

면접 예상 질문과 답변

Q1. 기본 타입과 참조 타입의 메모리 할당 방식?

A1. 기본 타입은 스택 메모리에 값이 저장되고 참조되고 참조 타입은 객체의 주소를 스택 메모리에 저장하고

실제 객체는 힙 메모리에 저장하게 됩니다.

 

Q2. 자바의 기본/원시 타입과 참조 타입의 장단점

A2. 기본 타입의 장점은 메모리 사용의 효율성과 빠른 연산이 가능하다는 장점이 있지만 객체 지향적인 기능에 제한이 있고

Null값을 가지지 못합니다.

참조 타입은 객체 지향적인 기능 활용에 용이하고 유연한 데이터 구조를 사용할 수 있는 장점이 있지만

메모리의 사용량이 기본타입에 비해 증가하고 연산속도가 감소한다는 단점이 존재합니다.

 

Q3. 기본 타입과 참조 타입의 사용 예시?

A3.  기본 타입은 주로 간단한 숫자나 논리값을 저장하는데 사용하고 참조 타입은 배열이나 인터페이스 등

다양한 객체들을 관리하는데 사용됩니다.

 

Q4. 기본/원시 타입과 참조 타입의 초기화 방식?

A4.  예를 들어 int형 변수에 따로 초기화를 하지 않으면 그 변수의 값은 0으로 자동 초기화가 되지만 참조 타입 변수는 null로 초기화가 됩니다.

따라서 참조 타입 사용 시 초기화를 하지 않는다면 런타임 시 NullPointerException가 발생될 수 있습니다.