[Java] 참조 타입에 대해서

2024. 3. 8. 23:27BE/Java

참조 타입은 객체의 주소를 참조하며 배열, 열거, 클래스, 인터페이스 타입이 있다.

 

메모리 영역

JVM이 실행되면 운영체제에서 메모리 영역(Runtime Data Area)을 할당 받는다.

 

메소드 영역

JVM이 프로그램을 실행하는데 필요한 클래스(.class)에 대한 메타데이터를 저장하는 영역이다.

이 영역에서 모든 스레드가 공유하고 클래스 파일에 있는 각각의 메소드, 변수, 상수 등에 대한 정보가 저장된다.

인스턴스 메소드는 객체마다 존재하지 않고 메소드 영역에서 저장되어 공유된다.

 

힙 영역

객체와 배열이 동적으로 할당되고 관리되는 영역이다.

힙 영역에서 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다.

참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 JVM은 Garbage Collector를 실행시켜 힙 영역에서 자동으로 제거한다.

 

JVM 스택 영역

각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.

자바 프로그램에서 추가적으로 스레드를 생성하지 않으면 main 스레드만 존재하기 때문에 JVM 스택이 하나다.

JVM 스택은 메소드를 호출할 때마다 Frame을 push하고 메소드가 종료되면 해당 frame을 pop한다.

Frame 내부에는 로컬 변수 스택이 있고 기본 타입 변수와 참조 타입 변수가 push되거나 pop된다.

로컬 변수 스택은 변수가 초기화 될 때 push된다.

public class Example {
    public static void main (String[] args) {
        char v1 = 'A';
        if (v1 == 'A') {
            int v2 = 100;
            double v3 = 3.14;
        }
        boolean v4 = true;
    }
}

 

변수가 선언된 블록을 벗어나는 경우 스택 영역에서 제거된다.

 

참조 변수의 동등 비교 연산

참조 타입에서 동등 비교 연산은 값이 같은지 판단하는게 아니라 동일한 객체를 참조하고 있는지 판단한다.

참조 변수의 값이 힙 영역 객체 주소 값을 저장하므로 동일한 객체인 경우 true 값을 산출한다.

public class Example {
    public static void main (String[] args) {
        String str1 = new String("test");
        String str2 = new String("test");

        System.out.println(str1 == str2); // false
    }
}

 

null 과 NullPointerException

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 의미로 null 값을 할당할 수 있다.

런타임 시 null로 할당된 참조 변수를 사용하면 NullPointerException 예외가 발생한다.

public class Example {
    public static void main (String[] args) {
        int[] intArray = null;
        intArray[0] = 10; // NullPointerException
    }
}

 

String 타입

자바에서 문자열은 String 객체로 생성되는데 문자열 리터럴이 동일한 경우 동일한 String 객체를 참조한다.

하지만 new 연산자로 힙 영역에 새로운 객체를 만드는 경우 문자열 리터럴이 동일하더라도 서로 다른 객체를 생성할 수 있다.

 

String 객체가 동일한지 상관없이 문자열만 같은지 확인하려면 String 객체의 equals 메소드를 사용하면 된다.

 

배열 타입

배열도 객체인데 동일한 타입의 데이터를 여러 개 저장하고자 할 때 사용한다.

한 번 생성된 배열은 길이를 변경할 수 없다.

 

배열 선언

배열 변수를 선언하는 방식은 대괄호가 타입 뒤에 붙거나 변수명 뒤에 붙이면 된다.

public class Example {
    public static void main (String[] args) {
        int[] array;
        int array[];
    }
}

 

 

배열 생성

목록으로 배열 생성

public class Example {
    public static void main (String[] args) {
        int[] array = { 1, 2, 3, 4, 5 };
        array = { 1, 2, 3, 4, 5 }; // error
    }
}

 

중괄호를 사용하여 배열 변수에 할당하는 경우 선언과 동시에 초기화하는 경우에만 가능하다.

 

new 연산자로 배열 생성

new 연산자를 사용해 배열 객체를 생성할 수 있다.

public class Example {
    public static void main (String[] args) {
        int[] array;
        array = new int[]{1, 2, 3, 4, 5};
    }
}

 

 

배열 객체를 길이만 설정하여 생성할 수도 있다.

public class Example {
    public static void main (String[] args) {
        int[] array = new int[5]; // 모두 0으로 초기화
    }
}

 

배열 길이

배열 객체 필드 length는 배열 길이를 나타낸다.

 

배열 복사

배열은 길이를 변경할 수 없기 때문에 새로 만들려면 기존 배열을 복사해서 사용하면 된다.

반복문을 사용하거나 System.arraycopy 메소드를 이용해서 복사하면 된다.

 

System.arraycopy ( oldArray, oldArrayStartIndex, newArray, newArrayStartIndex, lengthToCopy);

public class Example {
    public static void main (String[] args) {
        int[] array = {1,2,3,4,5};
        int[] copy = new int[30];

        System.arraycopy(array, 0, copy, 0, 3);

        for (int i=0; i<copy.length; i++) {
            System.out.println(copy[i]);
        }
    }
}

 

향상된 for문

카운터 변수와 증감식 없이 for문을 실행할 수 있다.

public class Example {
    public static void main (String[] args) {
        int[] array = {1,2,3,4,5};

        for (int i : array) {
            System.out.println(i);
        }
    }
}

 

열거 타입

열거 객체를 갖는 데이터 타입이다.

관례적으로 열거 변수명은 Pascal Case로 열거 상수는 모두 대문자로 표현한다.

공백은 언더바로 표현한다.

 

열거 타입 선언

public class Example {
    public static void main (String[] args) {
        enum Values { E1, E2, E3 };
        Values val = Values.E1;
        System.out.println(val); // E1
    }
}

 

열거 객체 메소드

열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있다.

 

name 메소드

열거 객체 문자열을 리턴한다.

열거 타입을 정의할 때 사용한 상수 이름과 동일하다.

ordinal 메소드

전체 열거 객체 중 몇 번째 열거 객체인지 알려준다.

compareTo 메소드

매개변수로 주어진 열거 객체를 기준으로 전후로 몇 번째 위치하는지 비교한다.

열거 객체가 매개값의 열거 객체보다 순번이 빠르면 음수로 느리면 양수를 리턴한다.

public class Example {
    public static void main (String[] args) {
        enum Values { E1, E2, E3 };

        System.out.println(Values.E2.compareTo(Values.E3)); // 순번 1 빠르므로 -1

    }
}

valueOf 메소드

매개변수로 주어진 문자열과 동일한 문자열을 가지는 열거 객체를 리턴한다.

public class Example {
    public static void main (String[] args) {
        enum Values { E1, E2, E3 };

        System.out.println(Values.valueOf("E2"));
    }
}

values 메소드

열거 타입의 모든 열거 객체들을 배열로 만들어서 리턴한다.

 

 

 

 

728x90

'BE > Java' 카테고리의 다른 글

[Java] 객체 지향 프로그래밍 이해하기  (0) 2024.03.09
[Java] 조건문과 반복문  (0) 2024.03.08
[Java] 연산에 대해  (0) 2024.03.07
[Java] 타입 변환  (0) 2024.03.07
[Java] 데이터 타입  (0) 2024.03.07