중요 !! 대원칙: 자바는 항상 변수의 값을 복사해서 대입한다.
자바에서 변수에 값을 대입하는 것은 변수에 들어 있는 값을 복사해서 대입하는 것이다.
기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어 있는 실제 사용하는 값을 복사 해서 대입하고, 참조형이면 변수에 들어 있는 참조값을 복사해서 대입한다.
이 대원칙을 이해하면 복잡한 상황에도 코드를 단순하게 이해할 수 있다.
기본형 대입
int, long, double, boolean처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입으로 기본형은 다 소문자로 시작!! 그럼 Strin은? 기본형이 아니라, 참조형이다.
int a = 10;
int b = a;
참조형 대입
Student student1, int[] students와 같이 데이터에 접근하기 위한 참조형 주소를 저장하는 데이터 타입을 의미한다. 객체, 배열에 사용된다.
Student s1 = new Student();
Student s2 = s1;
s2에는 실제 위치가 들어가는 것이고 객체가 2개가 형성되는 것이 아니다. 실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만 복사된다. 쉽게 말해, 기본형(int, double, boolean)을 제외하면 모두 참조형이다.
중요 !! 대원칙: 자바는 항상 변수의 값을 복사해서 대입한다.
기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형일 경우 변수에 들어있는 실제 사용값을 대입하고 참조형일 경우 들어있는 참조값을 복사해서 전달한다.
package ref;
public class MethodChange1 {
public static void main(String[] args) {
int a = 10;
System.out.println("메서드 호출 전: a = " + a);
changePrimitive(a);
System.out.println("메서드 호출 후: a = " + a);
}
static void changePrimitive(int x) {
x = 20;
} }
package ref;
public class MethodChange2 {
public static void main(String[] args) {
Data dataA = new Data();
dataA.value = 10;
System.out.println("메서드 호출 전: dataA.value = " + dataA.value);
changeReference(dataA);
System.out.println("메서드 호출 후: dataA.value = " + dataA.value);
}
static void changeReference(Data dataX) {
dataX.value = 20;
}
}
기본형: 메서드로 기본형 데이터를 전달하면, 해당 값이 복사되어 전달된다. 이 경우, 메서드 내부에서 매개변수 (파라미터)의 값을 변경해도, 호출자의 변수 값에는 영향이 없다.
참조형: 메서드로 참조형 데이터를 전달하면, 참조값이 복사되어 전달된다. 이 경우, 메서드 내부에서 매개변수(파 라미터)로 전달된 객체의 멤버 변수를 변경하면, 호출자의 객체도 변경된다.
멤버변수는 객체에 속하고 상태가 있는 것이고 지역변수는 함수에서 선언한 변수이다. 지역변수 명은 해당 함수에만 있고, 멤버 변수는 클래스 정의에서 선언한 변수이고, 그 수명은 해당 클래스 내부에만 있다.
int )= 0 , boolean = false , 참조형 = null ( null 값은 참조할 대상이 없다는 뜻으로 사용 된다.)택배를 보낼 때 제품은 준비가 되었지만, 보낼 주소지가 아직 결정되지 않아서, 주소지가 결정될 때 까지는 주소지를 비 워두어야 할 수 있다.
참조형 변수에는 항상 객체가 있는 위치를 가리키는 참조값이 들어간다. 그런데 아직 가리키는 대상이 없거나, 가리키는 대상을 나중에 입력하고 싶다면 어떻게 해야할까?
참조형 변수에서 아직 가리키는 대상이 없다면 null 이라는 특별한 값을 넣어둘 수 있다. null 은 값이 존재하지 않 는, 없다는 뜻이다.
data 에 null 을 할당했다. 따라서 앞서 생성한 x001 Data 인스턴스를 더는 아무도 참조하지 않는다. 이렇게 아무 도참조하지않게되면 x001 이라는참조값을다시구할방법이없다.따라서해당인스턴스에다시접근할방법이없 다.
이렇게 아무도 참조하지 않는 인스턴스는 사용되지 않고 메모리 용량만 차지할 뿐이다.
C와 같은 과거 프로그래밍 언어는 개발자가 직접 명령어를 사용해서 인스턴스를 메모리에서 제거해야 했다. 만약 실수 로 인스턴스 삭제를 누락하면 메모리에 사용하지 않는 객체가 가득해져서 메모리 부족 오류가 발생하게 된다.
자바는 이런 과정을 자동으로 처리해준다. 아무도 참조하지 않는 인스턴스가 있으면 JVM의 GC(가비지 컬렉션)가 더 이상 사용하지 않는 인스턴스라 판단하고 해당 인스턴스를 자동으로 메모리에서 제거해준다.
package ref;
public class InitData {
public static void main(String[] args) {
Data data = null;
System.out.println("Data: " + data);
data = new Data();
System.out.println("Data: " + data);
}
}
김영한 - 실전 자바