티스토리 뷰
포스팅에 앞서 내용이 틀릴 수 있습니다.
해당 부분 지적 감사히 받습니다.
String Class (2부)로 넘어가기 전에 불변 객체에 대해 알아보자.
불변 객체에 대한 이해가 있어야 String Class 2부에서 설명할 내용이 원활하게 이해될 것 같아 부득이하게 불변 객체를 사이에 넣었다.
불변 객체란 무엇일까?
불변 객체 : 객체의 상태가 변하지 않는 객체. ( 생성자에서만 초기값 제공)
뜻 그대로 변하지 않는 객체라는 것이다.
자바에서의 불변객체는 한번 값이 정해진 후 다시 수정되면 안 된다는 원칙을 갖고 있다.
불변객체라고 따로 있는 것이 아니라, 개발자가 한번 정해진 값을 다시 바꾸지 못하게 개발하면 된다.
바로 연관되어 떠오르는 것이 있어야 한다.
바로 final이다.
final이 Class에 붙으면 상속 불가, 메서드에 붙으면 오버라이딩 불가, 변수에 붙으면 초기값 세팅 후 변환 불가이다.
불변객체는 필드에 final이 붙고, 생성자를 제외한 나머지 부분에서 해당 필드를 수정할 수 없으면 불변객체라고 보면 된다.
그렇다면 불변 객체가 필요한 이유가 무엇일까?
바로 사이드 이펙트를 방지하기 위해서이다.
사이드 이펙트(Side Effect) : 프로그래밍에서 어떤 작업이 주된 작업 외에 추가적인 부수효과를 일으키는 것 (부정적 효과)
추가적으로 캐시 안정성, 멀티스레드 안정성, 엔티티의 값 타입 등 여러 가지 것들에 긍정적인 효과가 있지만, 아직 다루지 않았으므로 설명은 나중에 하도록 하겠다.
String Class는 불변 객체이다.
어떻게 알 수 있냐면, 일단 String Class를 까보면 된다.
private final char value[];
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
실제로 String Class내에 있는 필드, 생성자이다.
String은 사실 char [] 배열 형태로 값을 받는다. (자바 Ver9부터 byte [] 형태로 받으며, 숫자 + 영어값만 받았을 경우 각 인덱스마다 1byte씩 차지하며 한글이 있으면 2byte씩 차지하게 하여 효율적인 메모리 관리로 개선)
value [] 앞에 final이 붙어있다.
또한 String(String str) 생성자가 final로 선언된 value []의 값을 수정하며, 이는 초기값이 있다면 먹지 않는다.
따라서 불변 객체의 조건을 만족한다.
그러면 이런 불변 객체에서는 값을 바꿀 수 없는 것일까?
결론적으로 값을 바꿀 순 없지만, 바꾼 것처럼 보이게 할 순 있다.
바로 메서드를 만들어서 새로운 객체의 참조값을 return 해주면 된다.
예시를 보자
Imu Class (불변객체)
public class Imu {
private int num ;
Imu(int i){
this.num = i;
}
public int getNum(){
return num;
}
public Imu add(int i){
return new Imu(this.num + i);
}
}
Main Class
public class Main {
public static void main(String[] args) {
Imu imu1 = new Imu(10);
Imu imu2 = imu1.add(20);
System.out.println("imu2 = " + imu2.getNum());
}
}
실행 결과
Imu Class는 불변 객체로 만들어졌다.
처음 객체가 생성될 때 말고는 num이 수정될 수가 없다.
따라서 add() 메서드를 통해 그냥 현재 객체의 num 값에 매개변수로 받은 값을 + 연산한 새 객체를 만들어서 참조값을 반환해 주면 된다.
반환받은 참조값을 getNum() 메서드를 통해 호출하면 우리는 마치 10+20 =30의 결과를 낸 것처럼 보인다.
주의
만약 Main Class가 아래와 같다면 실행결과가 어떻게 될 것 같은가
public class Main {
public static void main(String[] args) {
Imu imu1 = new Imu(10);
imu1.add(20);
System.out.println("imu2 = " + imu1.getNum());
}
}
실행 결과
분명 add()를 사용하였는데 값이 10으로 출력된 것을 볼 수 있다.
우리는 add() 메서드를 통해 10 + 20 이 생성된 새 객체의 주솟값을 반환받았는데, 그냥 해당 메서드만 실행시킬 경우에는 참조값을 저장하는 변수가 없다.
따라서 힙영역에서 추후 GC 당한다. (Garbage Collection)
불변 객체를 사용할 때는 반드시 객체 참조값을 리턴 받아 사용하자.
다시 한번 불변 객체가 중요한 이유는?
- 캐시 안정성
- 멀티스레드 안정성
- 엔티티의 값 타입
이 내용은 추후에 다시 다루겠다.
아마 고급 강의 때 다룰 수 있을 듯하다.
'기술스택 > 자바(Spring)' 카테고리의 다른 글
자바 래퍼 클래스 (Wrapper Class) (1) | 2025.02.15 |
---|---|
자바 String Class (2부) (1) | 2025.02.13 |
자바 String Class (1부) (0) | 2025.02.12 |
자바 최상위 Class Object (3) | 2025.02.11 |
자바 OCP(Open - Closed Principle)원칙 (3) | 2025.02.11 |
- Total
- Today
- Yesterday
- 상속
- 코딩테스트
- static
- 김영한 실전 자바 기초
- los 15
- lord of sql
- 프로그래머스
- Los
- samron
- los 15단계
- 백준 피보나치 수열
- 백준
- 김영한
- 김영한 실전 자바 기본
- 자바
- 백준 피보나치
- java
- 기술스택
- 상품을 구매한 회원 비율 구하기 파이썬
- webhacking.kr
- 스프링
- spring
- 코딩테스트 준비
- 프로그래머스 상품을 구매한 회원 비율 구하기
- extends
- 프로그래머스 상품을 구매한 회원 비율 구하기 파이썬
- zixem
- 김영한 실전 자바 중급
- samron3
- ys.k
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |