[Java] 배열

Erin Lee·2024년 3월 7일
0

배열이란?


동일한 타입의 데이터들을 연속적인 메모리 공간에 동적으로 저장되는 것을 말한다.
하나의 객체 안에 여러 요소, 값들을 넣을 수 있기 때문에 각 배열 요소마다 별도의 변수들을 생성할 필요가 없다.


배열의 특징


  • 배열은 인덱스 기반으로 연속적인 메모리 공간을 가지며 배열의 첫번째 요소는 0번째 인덱스에 저장된다. 인덱스는 1이 아닌 0부터 시작한다.

  • 배열은 동적으로 생성되는 클래스의 객체로 Object가 조상 클래스이며 참조형 변수이기 때문에 힙으로부터 메모리 할당을 받는다.
  • Object 클래스를 상속하며 Serializable과 Cloneable 인터페이스를 구현한다.

*여기서 Java의 Marker Interface란?

마커 인터페이스란 필드나 메서드가 없는 빈 인터페이스이다.
JVM에게 마커 인터페이스를 구현하는 클래스는 특정 속성을 가져 다르게 처리되어야 하는 것을 알리는 역할을 한다.

1. Serializable Interface

Serializable 인터페이스란 java.io 패키지에 있으며 객체를 직렬화할 때 사용되는 인터페이스다.

직렬화란?
객체를 다른 환경에 저장했다가 나중에 다시 불러와서 재구성 할 수 있게 만드는 과정을 말한다.

객체의 상태를 바이트 스트림으로 변환하는 매커니즘이다.

바이트 스트림(byte stream)이란?
1byte를 Input/Ouput할 수 있는 Stream으로, Byte로 구성된 텍스트, 동영상, 이미지, 음악 등과 같은 파일들을 처리하는데 사용된다.

Stream이란?
JDK8부터 도입된 기능이며 객체들을 사용 목적에 맞게 다른 형태의 결과물로 만들어내기 위해 변환시키는데 필요한 여건을 만들어준다.

배열이 Serializable 인터페이스를 구현하다고 하여 찾아보게 되었는데 이해한게 맞는 것인지 모르겠다..

Stream은 데이터들을 컬렉션 또는 배열 또는 I/O 작업을 통해 입력을 받는다.

그래서 직렬화때 바이트 스트림으로 변환하는 작업이 있기 때문에 배열이 이를 구현하기 위해 직렬화 인터페이스를 구현한다는 것인 것 같다.

2. Cloneable Interface

java.lang 패키지에 있으며 객체를 복제하는 것을 가능하게 한다.

배열은 기본적으로 Cloneable 인터페이스를 구현하기 때문에 명시적으로 구현할 필요가 없다.

그래서 배열을 복제하는 것이 가능하다.

int[] a = new int[5];
int[] b = a;

https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html 에 상속받은 method를 보면

Cloneable 인터페이스에서 받은 clone 메서드가 있다.

배열 복제 테스트를 해봤다.

public class Cloneable_3_2 {
    public static void main(String[] args) {

        int[] arr1 = new int[5];
        int[] arr2 = arr1;

        System.out.println(arr1);
        System.out.println(arr2); //같은 주소값을 참조하고 있는 것을 알 수 있다.
        
    }
}

배열의 종류

  • 1차원 배열 : 같은 유형의 데이터들을 연속적으로 저장할 수 있는 묶음이 하나인 배열이다.
  • 다차원 배열 : 1차원 배열을 여러개 갖고 있는 배열이다.

배열의 장점

  • 여러 데이터들을 저장시킬 수 있어 코드 최적화에 도움이되고 데이터를 정렬화시켜 저장할 수 있다.
  • 정렬화되었기 때문에 인덱스별 데이터들을 쉽게 불러올 수 있다.

배열의 단점

  • 크기가 고정되어 그 크기만큼만 데이터를 넣을 수 있고 크기를 늘리거나 줄일 수 없다
  • 크기를 바꾸려면 새로운 배열 객체를 만들어야해서 새로운 메모리 영역을 차지하게 되기 때문에 신중하게 해야한다.

배열의 메모리 구조

1. 배열 선언

배열을 선언할 땐 배열의 유형과 이름을 정해줘야한다. 선언 방법은 두가지가 있다.

데이터타입 배열이름[];
데이터타입[] 배열이름;

배열을 선언했다고 해서 실제로 존재하는 것은 아니고 컴파일러에게 해당 데이터 타입의 배열이 있다는 것만을 알려주는 것이기 때문에 배열의 참조 변수만 생성이 된다.

그렇기 때문에 이때는 배열의 크기를 지정해줄 수 없고 지정을 하면 컴파일 오류가 난다.

스택에 변수만 생성되고 null 상태가 된다.

이 상태에서 배열을 호출하려고 하면 참조하고 있는 값이 없기 때문에 null이 나오는 것이 아니라 에러가 뜬다.

2. 배열 생성

배열이름 = new 데이터타입[배열크기];

배열을 만들 때는 new 연산자를 사용하여 배열의 크기를 먼저 지정함으로써 메모리를 할당받는다.

배열의 길이는 배열이 생성될 때 설정되며 생성된 후에는 고정된다.

이렇게 생성까지 하면 힙에 배열의 메모리가 할당되고 arr 변수는 그 메모리 주소값을 참조한다.

즉, 참조변수는 배열의 주소값을 참조하고있기 때문에 number의 값을 호출한다면 참조하고 있는 힙에 저장된 배열 객체의 주소값을 가져온다.


3. 배열의 초기화

배열을 생성하고 배열에 메모리까지 할당하였으니 이제 초기화를 해줄 수 있다.

배열이름 = new 데이터타입[]{요소};

배열의 인덱스에 직접 값 넣어주기
배열명[인덱스] = {요소};

배열 생성부터 초기화 정리 해보기

public class Array_3_2 {
    public static void main(String[] args) {
        
        //1. 배열 선언
        int[] arr1;
        int arr2[];

        //2. 배열 생성
        arr1 = new int[5];
        arr2 = new int[5];

        //배열 호출
        System.out.println(arr1); //출력값 : [I@48cf768c

        System.out.println(arr2[3]); //출력값 : 0

        //3. 배열 초기화
        arr1 = new int[]{1, 2, 3, 4, 5}; 
        //이 방법은 new 연산자를 사용하여 새로운 배열을 생성 후 안에 요소까지 넣어주는 작업이다.
        //그렇기 때문에 arr1은 기존에 참조하고 있던 주소값이 아닌 새로 생성된 주소을 참조하게 된다.

        arr2[0] = 1;
        arr2[1] = 2;
        arr2[2] = 3;
        arr2[3] = 4;
        arr2[4] = 5;

    }
}

정리!

먼저 배열을 선언을 하면 스택 영역에 쌓이고 new 연산자로 인해 생성되면 힙의 메모리를 동적으로 할당 받아 동시에 스택에 쌓인 변수는 할당받은 힙의 저장 공간 주소값을 참조한다.

이때는 기본형 타입의 기본값들로 설정되며 각 배열의 요소값들을 추출하면 기본값들이 추출된다. 그리고 초기화를 해주면 각 인덱스 공간에 지정된 요소들로 할당된다.




출처
https://docs.oracle.com/cd/E19455-01/805-7478/6j71mbrcf/index.html
https://docs.oracle.com/cd/E19455-01/805-7478/6j71mbrcg/index.html
https://www.javatpoint.com/bytestream-classes-in-java
https://www.shrubbery.net/solaris9ab/SUNWdev/STREAMS/p4.html#OVERVW1-11181 https://www.geeksforgeeks.org/stream-in-java/
https://www.programcreek.com/2013/04/what-does-a-java-array-look-like-in-memory/
https://www.softwaretestinghelp.com/marker-interfaces-java/
https://www.geeksforgeeks.org/marker-interface-java/
https://www.javatpoint.com/array-in-java
https://www.geeksforgeeks.org/arrays-in-java/
https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html
https://www.geeksforgeeks.org/arrays-in-java/
https://www.tutorialspoint.com/where-does-array-stored-in-jvm-memory-in-java
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
https://www.javatpoint.com/array-in-java
https://linuxhint.com/create-array-java/

profile
내가 설명할 수 있어야 비로소 내가 아는 것이다

0개의 댓글