Java Study #5

allzeroyou·2022년 1월 28일
0

Java

목록 보기
5/14

1. 참조 자료형

자바에서는 8개의 기본 자료형 이외의 모든 자료형은 참조 자료형이다.
대표적인 참조 자료형에는 배열, 클래스, 인터페이스 등이 있다. 참조 자료형은 개발자가 얼마든지 정의할 수 있어 무한개라 할 수 있음.

1-1. 배열

  • 동일한 자료형을 묶어 저장하는 참조 자료형.
  • 생성할 때 크기를 지정해야
  • 한번 크기를 지정하면 절대 변경 불가

배열 생성하기

1단계 배열 선언하기

배열을 선언할 때는 2가지 방법으로 선언 가능
배열을 나타내는 대괄호([])는 자료형 뒤에 올 수 있고, 변수명 뒤에도 올 수 있음.
그러나 다른 자료형의 표현과 일관성 유지를 위해 자료형 뒤에 표기를 권장.

ex. int[] a;
double[] b;
String[] c;

정수 자료형을 int, 실수 자료형을 double이라고 한 것 처럼, 배열 자료형도 array라고 이름을 만들면 편할 텐데, 왜 자료형[] 방식을 사용?

배열은 동일한 자료형만 묶을 수 있는 자료형!
만일 array a와 같이 만들면 이 배열이 어떤 자료형을 묶은 것인지 알 수 없음.
그래서 int[] a, String[] b 처럼 선언해 배열 자료형을 보자마자 어떤 타입을 묶은 것인지 알 수 있도록함.

  • 배열을 선언하면 스택 메모리에 변수의 공간만 생성, 공간 안은 비운 채로 둔다.
  • 아직 배열의 실제 데이터인 객체를 생성하지 않았기 때문에!
  • 스택 메모리에 위치하고 있는 참조 자료형 변수의 빈 공간을 초기화할 때는 널(null)값을 사용 가능
    -null 값은 힙 메모리의 위치(번지)를 가리키고 있지 않다는 의미 = 연결된 실제 데이터 ㅇ벗음.

2단계 힙 메모리에 배열의 객체 생성

모든 참조 자료형의 실제 데이터(객체)는 힙 메모리에 생성. 힙 메모리에 객체를 생성하기 위해서는 new 키워드를 사용해야

배열의 객체 생성
new 자료형[배열의 길이]

  • 배열의 객체 생성 과정에서 배열의 두 번째 특징을 알 수 있음.
  • 배열을 생성할 때 new int[3]또는 new String[3] 처럼 배열의 길이를 반드시 지정해야 한다는 점이다.

3단계 배열 자료형 변수에 객체 대입

선언된 배열 참조 자료형 변수에 생성한 객체를 대입하는 데는 2가지 방법이 있는데, 변수 선언과 값(참조 자료형은 객체)의 대입을 한 번에 작성해도 되고 따로 구분해 작성해도 된다.
이는 기본 자료형에서 int a = 3과 같이 선언과 값을 한번에 대입하거나 int a로 변수를 선언한 후 a = 3으로 값을 대입할 수 있는 것과 동일한 개념

배열 참조 자료형 변수에 생성한 객체 대입
자료형[] 변수명 = new 자료형[배열의 길이];
ex. int [] a = new int[3];

int[]는 int 자료형만 저장할 수 있는 배열
a는 참조변수로 실제 데이터 값 저장 x
실제 데이터 값의 위치값을 저장
new 키워드는 힙 메모리에 객체를 넣으라는 의미
int [3] 은 정수 3개를 저장할 수 있는 공간을 만들라는 의미
=> int 자료형 3개를 저장할 수 있는 공간을 힙 메모리에 넣어 두고 어디에 넣었는지 참조 변수 a에 저장해!

  • 스택 메모리 공간은 값을 초기화하지 않으면 빈 공간으로 존재
  • 당연히 잉때 해당 변수를 출력하면 오류 발생
  • 반면 힙 메모리는 어떤 상황에서도 빈 공간이 존재하지 않는다.
  • 그래서 값을 주지 않으면 컴파일러가 값을 강제로 초기화
  • 강제 초기화 값은 자료형에 따라 다른데 기본 자료형일때는 숫자는 모두 0, boolean은 false, 이외 모든 참조 자료형은 null로 초기화

4단계 객체에 값 입력

배열은 값을 저장할 수 있는 공간마다 방 번호가 있는데 이 번호를 인덱스라고 한다.

  • 인덱스는 0부터 시작하며, 1씩 증가

참조 변수명[인덱스] = 값;
ex. int[] a = new int[3];
a[0]=3;
a[1]=4;
a[2]=5;

  • int[] a = new int [3]과 같이 처음 배열을 선언함과 동시에 객체를 생성하면 힙 메모리의 모든 값은 초기화 됨. 이때 배열의 자료형은 정수이므로 초기화 되는 값은 0이다.

  • 값을 읽을 때도 다음과 같이 인덱스를 사용

    참조 변수명[인덱스];
    System.out.println(a[0]);
    System.out.println(a[1]);
    System.out.println(a[2]);

  • 배열의 저장공간에 값을 대입하거나 읽을 때, 없는 인스를 사용하면 예외 발생하고 프로그램 종료

1차원 배열을 생성하는 다양한 방법

방법1 배열 객체를 생성하고 값 대입

자료형[] 참조변수명 = new 자료형[배열의 길이]; 참조 변수명[0] = 값; 참조 변수명[1] = 값; ... 참조 변수명[배열의 길이 - 1] = 값;

방법2 배열 객체 생성과 함께 값 대입

  • 배열 객체를 생성함과 동시에 값 대입
  • 초깃값을 직접 넣어주므로 컴파일러에게 강제 초기화 과정은 생략
  • 객체를 생성할 때 오른쪽 항의 대괄호([])안에 배열의 길이를 지정하지 않음
  • 하지만 배열의 길이는 다음에 나오는 중괄호({})안의 초기화 데이터 개수로 결정 => 배열의 특징 모두 만족

    자료형[] 참조 변수명 = new 자료형[]{값, 값,...,값}; ex.int[] a = new int[]{3,4,5};

방법3 대입할 값만 입력

  • new 키워드 없이 초기화할 값만 중괄호에 넣어 대입
  • 초기화 데이터 개수가 배열의 길이 결정

    자료형[] 참조 변수명 = {값, 값, ... 값); ex. int[] a = {3,4,5};

변수 선언과 값 대입의 분리 가능 여부

  • 방법3은 방법2에서 new int[]를 생략한 형태
  • 방법3에는 변수 선언과 값 대입을 분리할 수 없다는 제약 조건
  • 선언과 동시에 값을 대입할 때만 사용 가능
  • 선언과 대입을 분리할 수 없어 메서드의 입력매개변숫값으로 사용 불가

참조 자료형으로서 배열의 특징

  • 기본 자료형과 참조 자료형에서 변수를 복사할 때를 비교해보자.
  • 대입 연산자(=)를 이용해 변수가 복사되는 과정을 이해해야
  • 변수에 포함돼 있는 스택 메모리 값을 복사한다는 것임
  • 기본 자료형과 참조 자료형이 스택 메모리에 저장하는 값의 의미가 다르므로 자연스럽게 둘 사이에 차이 발생
  • 기본 자료형은 스택 메모리에 실제 데이터 값 저장 => 기본 자료형 변수를 복사하면 실제 데이터 값이 1개 더 복사. 복사된 값을 아무리 변경해도 원본 값은 영향 x
  • 참조 자료형은 스택 메모리에 실제 데이터 값이 아닌 힙 메모리에 저장된 객체의 위치 저장.
  • 참조 자료형 변수를 복사하면 실제 데이터 복사 x => 실제 데이터의 위치값 복사.
    => 하나의 참조 변수를 이용해 데이터 수정시 다른 참조 변수가 가리키는 데이터 변함.

배열의 길이

  • 자바는 배열 참조 변수.length로 배열의 길이를 구할 수 있는 방법 제공.
  • 포인트 연산자(.)는 해당 참조 변수가 가리키는 곳으로 가라라는 의미
  • length는 객체에 포함된 읽기 전용 속성으로, 배열 객체의 방 개수에 해당하는 값 지님
  • 배열 참조 변수가 가리키는 곳에가면 배열 객체가 있는데, 그 배열의 방 개수를 가져와!

배열 참조 변수.length
int[] a = new int[]{3,4,5};
System.out.print(a.length); //3

  • for-each 문을 사용하는 방법도 있음.

  • for-each문은 배열이나 컬렉션 등의 집합 객체에서 원소들을 하나씩 꺼내는 과정을 반복하는 구문

  • 집합 객체의 원소들을 출력할 때 사용.

    for(원소 자료형 변수명: 집합 객체){ }

  • 배열의 각 원소 값을 출력하는 마지막 방법: Arrays 클래스의 toString() 정적 메소드를 사용

  • System.out.println(Arrays.toString(1차원 배열 참조 변수))를 실행하면 모든 배열의 원소가 출력!

1-2. 2차원 정방 행렬 배열

가로 및 세로 방향으로 2차원 데이터를 저장하는 배열
직사각형의 형태로 모든 행의 길이가 같은 배열을 2차원 정방 행렬 배열이라고 함.
int[][] a;

  • 2차원 배열은 각 정보가 2개의 인덱스 쌍으로 이뤄짐

  • 위치 표현은 세로 방향으로 숫자가 늘어가는 행 번호와 가로 방향으로 숫자가 늘어가는 열 번호로 구성

  • 각 방향의 인덱스는 0부터 시작

  • a[2][1]은 2차원 배열 a의 세번째 행과 두번째 열을 의미!

  • 그러나 메모리는 2차원 데이터를 바로 저장 x

  • 2차원 배열은 1차원 배열을 워소로 포함하고 있는 1차원 배열!

방법 1 배열 객체 생성하고 값 대입

2차원 배열 객체 선언 후 각각의 인덱스 위치에 값을 대입하는 것

자료형[][] 참조변수명 = new 자료형[행의길이][열의길이];
참조 변수명 [0][0] = 값;
참조 변수명 [0][1] = 값;
...
참조 변수명 [행의 길이 -1][열의 길이 -1] - 값;

방법 2 배열 객체의 행 성분부터 생성하고 열 성분 생성하기

2차원 배열의 행 성분만 먼저 생성하고, 각 행에 열 성분을 생성하는 것.
다소 복잡해보이지만, 2차원 배열의 메모리 구조를 이해하면 쉽게 이해 가능

자료형[][] 참조 변수명 = new 자료형[행의 길이][];
참조 변수명[0] = 1차원 배열의 생성;
참조 변수명[1] = 1차원 배열의 생성;
...
참조 변수명[행의 길이 - 1] = 1차원 배열의 생성;

방법 3 배열의 자료형과 함께 대입할 값 입력

배열의 크기가 대입되는 초기값의 수에 따라 결정. 대괄호 안에는 반드시 크기를 지정하지 않아야 한다.

자료형[][] 참조 변수명 = new 자료형[][] {{값, 값,...,값},{값, 값, ...,값}};

방법 4 대입할 값만 입력

자료형[][] 참조 변수명 = {{값, 값, 값,...,값},{값, 값, ..., 값}};
선언과 값의 대입 분리 x

1-3. 2차원 비정방 행렬 배열

각 행마다 열의 길이가 다른 2차원 배열.
기본적인 개념은 2차원 정방 행렬 배열과 동일.
1차원 배열을 원소로 포함하고 있는 1차원 배열인 셈, 원소인 1차원 배열들의 길이가 다양하다는 것에 차이가 있음.

방법 1 배열 객체의 행 성분부터 생성하고 열 성분 생성

자료형[][] 참조 변수명 = new 자료형[행의 길이];

방법 2 자료형과 대입할 값만 입력

자료형과 함께 이중 중괄호를 사용해 생성할 때 초깃값을 넘겨주는 것이다. 대괄호 안에 행렬의 크기를 넣지 않으며, 초깃값에 따라 각 행마다 들어갈 배열의 길이가 결정

자료형[][] 참조변수명 = new 자료형[][] {{값, 값, 값...값},{값, 값, 값,...,값}};

방법 3 대입할 값만 입력

자료형[][] 참조 변수명 = {{값, 값, ..., 값},{값, 값, ..., 값}};

  • 선언과 대입 분리 x

1-4. 2차원 배열의 출력

2차원 배열은 가로, 세로 방향이 있으므로 2개의 인덱스 사용
모든 데이터 출력을 위해서는 이중 for 문을 사용해야
반복 횟수는 바깥쪽 for 문에서는 행의 개수를 나타내는 a.length를 안쪽 for 문에서는 각 행별 열의 개수를 나타내는 a[i].length를 사용해야

2. 문자열을 저장하는 string

참조 자료형의 가장 대표적인 예는 클래스이다.
자바가 제공하는 클래스 중 문자열을 저장하는 string 클래스를 알아보자.

2-1. 문자열의 표현과 객체 생성

String a = "문자열"
큰 따옴표 안 생략 가능

2-2. String 클래스의 2가지 특징

특징 1 객체 안의 값을 변경하면 새로운 객체 생성

참조 자료형에서 2개의 참조 변수가 1개의 객체를 가리킬 때 하나의 참조 변수에 접근해 객체의 값을 변경하면, 다른 참조 변수가 가리키는 값도 함께 변하는 것과 구분되는 특징임.

특징 2 리터럴을 바로 입력한 데이터는 문자열이 같을 때 하나의 객체를 공유

문자열 리터럴만 입력해 String 객체를 생성하면 하나의 문자열을 여러 객체가 공유 가능.
다른 클래스에 없는 특징으로 특정 문자열의 객체를 여러개 만들어 사용할 때 메모리 효율성 증가시키기 위함.

String 객체의 '+' 연산

  • 유형 1 '문자열 + 문자열' 연산
    string객체의 내용을 변경할 수 없으므로 메모리에는 각각의 문자열 리터럴 객체가 만들어진다.
  • 유형 2 '문자열 + 기본 자료형' 또는 '기본 자료형 + 문자열' 연산
    모든 연산은 동일한 자료형끼리만 가능. 따라서 기본 자료형과 문자열을 연산하려면 먼저 기본 자료형을 문자열로 바꾸고 이어서 '문자열 + 문자열' 연산을 수행한다.

String 클래스의 주요 메소드

-length(): 문자열의길이 리턴
-charAt(): 문자열에서 특정 인덱스에 위치해 있는 문자를 알아낸다.
-indexOf(): 문자열에서 특정 문자나 특정 문자열을 앞에서부터 찾아 위칫값을 알아낸다.
-lastIndexOf(): 문자열에서 특정 문자나 특정 문자열을 뒤에서부터 찾아 위칫값을 알아낸다.
-String.valueOf(): 기본 자료형을 문자열로 바꾸는 정적 메소드
-concat(): 2개의 문자열을 연결(+연산자와 동일한 기능 수행)
-getBytes(): 문자열을 byte 배열로 변환. 자바 입출력 과정에서 사용
-toCharArray(): 문자열을 char 배열로 변환. 자바 입출력 과정에서 사용

📕 참고문헌) Do it! 자바 완전 정복!

profile
모든 건 zero 부터, 차근차근 헛둘헛둘

0개의 댓글