데이터 타입
[Java] 변수와 데이터 타입이란?
변수(variable)란? 💡말 그대로 변하는 수 즉, 고정되지 않은 수를 변수라고 의미한다. 프로그래밍 언어에선 변수란 값을 저장할 수 있는 메모리상의 공간을 의미한다. 변수의 선언과 초기화 변수
hyun-dev-com.tistory.com
상단 링크에 기본형과 참조형 타입에 대해 간단하게 정리했으니 참고 하시길 바랍니다.
기본형 타입 (Primitive Type)이란?
⚠️ 하나의 값을 여러 변수에서 절대로 공유하지 않는다.
💡 Java에서 변수 기본형 타입은 총 8가지가 존재하며,
실제 데이터를 저장하기 위해 사용되는 변수 타입이다.
⬇️ 하단 간단한 예시를 통해 자세히 알아보려한다.
public class PrimitiveMain {
public static void main(String[] args) {
// 기본형은 절대로 같은 값을 공유하지 않는다.
int a = 10;
int b = a; // a-> b, 값 복사 후 대입
System.out.println("a = " + a); // 실행 결과 ➡️ 10
System.out.println("b = " + b); // 실행 결과 ➡️ 10
b = 20; // b만 값 20으로 변경
System.out.println("20 -> b");
System.out.println("a = " + a); // 실행 결과 ➡️ 10
System.out.println("b = " + b); // 실행 결과 ➡️ 20
}
}
실행 결과
a = 10
b = 10
20 -> b
a = 10
b = 20
예제 소스 설명
➡️ 기본형 변수 a와 b는 절대로 하나의 값을 공유하지 않는다.
➡️ b = a라고 하면 Java는 항상 값을 복사해서 대입한다.
이 경우 a에 있는 값 10을 복사해서 b에 전달한다.
➡️ 결과적으로 a와 b는 둘다 10이라는 똑같은 숫자의 값을 가진다.
하지만 a가 가지는 10과 b가 가지는 10은 복사된 완전히 다른 10이다.
메모리 상에서도 a에 속하는 10과 b에 속하는 10이 각각 별도로 존재한다.
➡️ b = 20이라고 하면, b의 값만 20으로 변경된다.
➡️ a의 값은 10으로 그대로 유지된다.
➡️ 기본형 변수는 하나의 값을 절대로 공유하지 않는다.
따라서 값을 변경해도 변수 하나의 값만 변경된다.
여기서는 변수 b의 값만 20으로 변경되었다.
참조형 타입 (Reference Type)이란?
⚠️ 하나의 객체를 참조값을 통해, 여러 변수에서 공유할 수 있다.
💡 기본형 타입을 제외한 모든 타입을 의미한다.
기본형 타입과 다르게 빈 객체 (Empty Object)를 의미하는 Null 값이 존재한다.
⬇️ 하단 간단한 예시를 통해 자세히 알아보려한다.
단순히 주소를 보관하는 객체
public class Address {
private String value;
public Address() {
}
public Address(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Address{" +
"value='" + value + '\'' +
'}';
}
}
참조형 변수 공유 테스트
public class RefMain1_1 {
public static void main(String[] args) {
// 참조형 변수는 하나의 인스턴스를 공유할 수 있다.
Address a = new Address("서울");
Address b = a;
// toString()을 재정의 했기에, 변수 값 출력
System.out.println("a = " + a); // 실행 결과 ➡️ Address{value='서울'}
System.out.println("b = " + b); // 실행 결과 ➡️ Address{value='서울'}
b.setValue("부산"); // b의 값을 부산으로 변경
System.out.println("부산 -> b");
System.out.println("a = " + a); // 실행 결과 ➡️ Address{value='부산'} + 사이드 이펙트 발생
System.out.println("b = " + b); // 실행 결과 ➡️ Address{value='부산'}
}
}
실행 결과
a = Address{value='서울'}
b = Address{value='서울'}
부산 -> b
a = Address{value='부산'}
b = Address{value='부산'}
예제 소스 설명
Address a = new Address("서울");
Address b = a;
➡️ 참조형 변수들은 같은 참조값을 통해 같은 인스턴스를 참조할 수 있다.
➡️ b = a라고 하면, a에 있는 참조값 x001을 복사해서 b에 전달한다.
➡️ 참조값을 복사해서 전달하므로, 결과적으로 a, b는 같은 x001 인스턴스를 참조한다.
➡️ 기본형 변수는 절대로 같은 값을 공유하지 않는다.
ex) a=10, b=10과 같이 같은 모양의 숫자 10이라는 값을 가질 수는 있지만, 값을 공유하는건 아니다.
즉, 서로 다른 숫자 10이 두 개 있는 것이다.
여기서 b의 주소만 부산으로 변경했는데, a의 주소도 함께 부산으로 변경되었다.
같은 인스턴스를 참조해서 변경이 된 것이다.
공유 참조 간 사이드 이펙트 (Side Effect)
💡 사이드 이펙트(Side Effect)란?
프로그래밍에서 어떤 계산이 주된 작업 외,
추가적인 부수 효과를 일으키는 것을 의미한다.
앞서 b의 값을 부산으로 변경한 코드를 분석하며 알아보려한다.
b.setValue("부산"); // b의 값을 부산으로 변경
System.out.println("부산 -> b");
System.out.println("a = " + a); // 실행 결과 ➡️ Address{value='부산'} + 사이드 이펙트 발생
System.out.println("b = " + b); // 실행 결과 ➡️ Address{value='부산'}
➡️ b의 주소값만 서울에서 부산으로 변경할 의도로 값 변경을 시도했다.
➡️ 하지만 a, b는 같은 인스턴스를 참조한다. 따라서 a의 값도 함께 부산으로 변경된다.
위와 같이 추가적인 부수 효과를 일으키는 것을 사이드 이펙트 (Side Effect)라고 한다.
보통 프로그래밍에서 부정적인 의미로 사용되는데,
프로그램의 특정 부분에서 발생한 변경이 의도치 않게 다른 부분에 영향을 미치는 경우에 발생한다.
이로 인해 디버깅이 어려워지고, 코드의 안정성이 저하될 수 있다.
사이드 이펙트 해결방안 (Side Effect Solution)
💡 생각해보면 문제의 해결방안은 아주 단순하다.
다음과 같이 a와 b가 처음부터 서로 다른 인스턴스를 참조하면 된다.
Address a = new Address("서울");
Address b = new Address("서울");
⬇️ 하단 간단한 예시를 통해 자세히 알아보려한다.
public class RefMain1_2 {
public static void main(String[] args) {
// 참조형 변수는 하나의 인스턴스를 공유할 수 있다.
Address a = new Address("서울"); // x001
Address b = new Address("서울"); // x002
System.out.println("a = " + a); // 실행 결과 ➡️ Address{value='서울'}
System.out.println("b = " + b); // 실행 결과 ➡️ Address{value='서울'}
b.setValue("부산"); // b의 값을 부산으로 변경
System.out.println("부산 -> b");
System.out.println("a = " + a); // 실행 결과 ➡️ Address{value='서울'}
System.out.println("b = " + b); // 실행 결과 ➡️ Address{value='부산'}
}
}
실행 결과
a = Address{value='서울'}
b = Address{value='서울'}
부산 -> b
a = Address{value='서울'}
b = Address{value='부산'}
➡️ 하a와 b는 서로 다른 인스턴스를 참조한다.
따라서 b가 참조하는 인스턴스의 값을 변경해도 a에는 영향을 주지 않는다.
⚠️ 여러 변수가 하나의 객체를 공유하는 것을 막을 방법은 없다.
💡 개발자가 실수로 b = a라고 해도 프로그램에서 오류가 발생하지도 않는다.
Java 문법 상 Address b = a와 같은 참조형 변수 대입은 아무런 문제가 없기 때문이다.
하지만 때로는 객체의 공유가 필요할 때가 있기 때문에, 코드를 잘 작성해야한다.
OUTRO
오늘은 기본형 타입과 참조형 타입에 대해서 알아봤습니다.
참조형에서 객체 공유를 막을 방법이 없기에 사이드 이펙트가 발생한 것 인데,
문제의 원인은 공유된 객체의 값을 변경한 것에 있었습니다.
이러한 값 변경을 제어하고자, 필드의 값을 변경할 수 없게 클래스를 설계해야합니다.
따라서 다음 포스팅에는 불변 객체에 대해서 알아보려합니다.
그러면 다음 포스팅에서 뵙겠습니다.
위 포스팅 글은 김영한님의 실전 자바 - 중급 1편을 참고했습니다.
김영한의 실전 자바 - 중급 1편 | 김영한 - 인프런
김영한 | 실무에 필요한 자바의 다양한 중급 기능을 예제 코드로 깊이있게 학습합니다., [사진]국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바
www.inflearn.com
'Language > Java' 카테고리의 다른 글
[Java] String (문자열) 이란? + (특징, 클래스 구조, 메서드) (0) | 2024.04.12 |
---|---|
[Java] 불변 객체 (Immutable Object)란? (0) | 2024.04.08 |
[Java] 클래스, 객체, 메서드, 생성자 (0) | 2024.03.30 |
[Java] 연산자 (Operator) (0) | 2024.03.29 |
[Java] 변수와 데이터 타입이란? (0) | 2024.03.26 |