변수의 데이터 타입을 가장 크게 보면 기본형과 참조형으로 분류할 수 있다.
기본형 (Primitive Type)
int, long, double, boolean 처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입
참조형(Reference Type)
Student student1, int[] students 와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입
기본형을 제외한 나머지는 모두 참조형이다.
참고 - String
자바에서 String은 특별하다. String 은 사실은 클래스다. 따라서 참조형이다. 그런데 기본형처럼 문자 값을 바로 대입할 수 있다.
문자는 매우 자주 다루기 때문에 자바에서 특별하게 편의 기능을 제공한다.
대원칙: JAVA 는 항상 변수의 값을 복사해서 대입한다.
기본형 대입
int a = 10;
int b = a;
기본형은 변수에 값을 대입하더라도 실제 사용하는 값이 변수에 바로 들어있기 때문에 해당 값만 복사해서 대입한다.
참조형 대입
Student s1 = new Student();
Student s2 = s1;
참조형의 경우 실제 사용하는 객체가 아니라 객체의 위치를 가르키는 참조값만 복사된다.
Student s1 = x100;
Student s2 = s1;
기본형과 변수 대입 간단한 예제
package class1;
public class VarChange1 {
public static void main(String[] args) {
int a = 10;
int b = a;
System.out.println("a: " + a);
System.out.println("b: " + b);
// a 변경
a = 20;
System.out.println("a: 변경 = 20");
System.out.println("a: " + a);
System.out.println("b: " + b);
// b 변경
b = 30;
System.out.println("b: 변경 = 30");
System.out.println("a: " + a);
System.out.println("b: " + b);
}
}
a: 10
b: 10
a: 변경 = 20
a: 20
b: 10
b: 변경 = 30
a: 20
b: 30
결과를 보면 a 가 b 인것이 아니다.
a 에 있는 기본형 값을 b 에 저장하는 것이다.
참조형과 변수 대입 간단한 예제
Data 라는 클래스를 생성합니다.
package class1;
public class Data {
int value;
}
package class1;
public class VarChange2 {
public static void main(String[] args) {
Data dataA = new Data();
dataA.value = 10;
Data dataB = dataA;
dataB = dataA;
System.out.println("dataA.value: " + dataA.value);
System.out.println("dataB.value: " + dataB.value);
// dataA 변경
dataA.value = 20;
System.out.println("dataA.value: 변경 = 20");
System.out.println("dataA.value: " + dataA.value);
System.out.println("dataB.value: " + dataB.value);
// dataB 변경
dataB.value = 30;
System.out.println("dataB.value: 변경 = 30");
System.out.println("dataA.value: " + dataA.value);
}
}
dataA.value: 10
dataB.value: 10
dataA.value: 변경 = 20
dataA.value: 20
dataB.value: 20
dataB.value: 변경 = 30
dataA.value: 30
이번에는 결과를 보면 a 가 b 인것이다.
이유는 참조형은 값 안에 주소가 들어가 있기 때문에 그 주소를 복사해서 가져가서 값이 동일하게 되는 것이다.
메서드를 호출할 때 사용하는 매개변수(파라미터)도 결국 변수이다.
기본형과 메서드 호출
package class1;
public class VarChange3 {
public static void main(String[] args) {
int a = 10;
System.out.println("메서드 호출 전: a = " + a);
changeValue(a);
System.out.println("메서드 호출 후: a = " + a);
}
public static void changeValue(int a) {
a = 20;
System.out.println("메서드 내부: a = " + a);
}
}
메서드 호출 전: a = 10
메서드 내부: a = 20
메서드 호출 후: a = 10
결과를 보면 changeValue 에서 쓰이는 a (기본형) 값이 복사가 되기 때문에 바꿔지지 않는 것이다.
참조형과 메서드 호출
package class1;
public class VarChange4 {
public static void main(String[] args) {
Data dataA = new Data();
dataA.value = 10;
System.out.println("메서드 호출 전: dataA.value = " + dataA.value);
changeDataValue(dataA);
System.out.println("메서드 호출 후: dataA.value = " + dataA.value);
}
public static void changeDataValue(Data data) {
data.value = 20;
System.out.println("메서드 내부: data.value = " + data.value);
}
}
메서드 호출 전: dataA.value = 10
메서드 내부: data.value = 20
메서드 호출 후: dataA.value = 20
이번에는 바뀌게 된다. 이유는 data 의 값을 changeDataValue 에서 참조형의 주소를 복사하기 때문에 주소에 접근한 데이터 value 를 바꾸게 되면 value 도 바뀌게 되는 것이다.