JAVA
[Java] 기본형 vs 참조형
songsua
2024. 10. 19. 01:57
- 기본형(Primitive Type): `int` , `long` , `double` , `boolean` 처럼 변수에 사용할 값을 직접 넣을 수 있는 데이 터 타입을 기본형이라 한다.
- 참조형(Reference Type): `Student student1` , `int[] students` 와 같이 데이터에 접근하기 위한 참조 (주소)를 저장하는 데이터 타입을 참조형이라 한다. 참조형은 객체 또는 배열에 사용된다
메서드 호출
package ref;
public class MethodChange02 {
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;
}
}
int 형인 기본형에 대한 메서드 호출인 경우,
a = 10 인 값은 그대로 가지고 가기 때문에, 메서드 a 값을 호출 하면 10 이 나온다.
그렇다면 참조형 변수의 메서드 호출은 어떨까?
package ref;
public class Methodchange01 {
public static void main(String[] args) {
Data data1 = new Data();
data1.value = 10;
System.out.println("메서드 호출 전: " + data1.value);
Change(data1);
System.out.println("메서드 호출 후 :" + data1.value);
}
static void Change(Data datax) {
datax.value = 100;
}
}
메서드 호출 전은 data1의 value 값 10을 가져왔다.
메서드 호출 후는 data x 의 100 을 가져오는데, 왜 그럴까?
data1 의 참조값 10을 가지고 있다.
같은 change 메서드에서 dataA 값을 가지고 있던 것을 dataX 의 값을 복사하여 가지게 된다.
기본형에 대한 메서드 호출은 그 값에 대한 복사이고
참조형에 대한 메서드 호출은 참조값을 복사하여 그대로 가져가게 된다.
- **기본형**: 메서드로 기본형 데이터를 전달하면, 해당 값이 복사되어 전달된다. 이 경우, 메서드 내부에서 매개변수 (파라미터)의 값을 변경해도, 호출자의 변수 값에는 영향이 없다.
- **참조형**: 메서드로 참조형 데이터를 전달하면, 참조값이 복사되어 전달된다. 이 경우, 메서드 내부에서 매개변수(파 라미터)로 전달된 객체의 멤버 변수를 변경하면, 호출자의 객체도 변경된다.
메서드를 사용하여 참조값을 넘기기
package ref;
public class Method03 {
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "학생";
student1.age = 12;
student1.grade = 78;
Student student2 = new Student();
student2.name = "학생2";
student2.age = 11;
student2.grade = 90;
//아래와 같은 println 을 사용하지 않고 static void 를 이용해서 호출하기
//System.out.println("이름:"+ student1.name + "나이 :" + student1.age + student1.grade + "성적");
//System.out.println("이름:"+ student2.name + "나이 :" + student2.age + student2.grade + "성적");
printStudent(student1);
printStudent(student2);
//1번의 참조값을 받아서 아래의 'printstudent'에게 값을 넘길 것이다.
}
//참조값을 넘겨보자
static void printStudent(Student student) {
System.out.println("이름:"+ student.name + " 나이 :" + student.age + " 성적: "+ student.grade );
}
}
- static: 이 키워드는 메서드가 인스턴스화된 객체와는 독립적으로 호출될 수 있음을 나타냅니다. 즉, 클래스의 인스턴스가 없어도 클래스 이름으로 직접 호출할 수 있습니다.
- void: 이 메서드가 아무 값도 반환하지 않음을 의미합니다. 즉, 결과를 출력하는 것이 목적이지, 다른 데이터로 반환되지는 않습니다.
아래와 같이 static void 매세더이름 (클래스 객체이름, 참조1, 참조2, 참조3 ) 넣어 둔 다음,
객체.변수 = 값 으로 하나하나 안적어도 아래와 같이 메서드를 이용해서 한꺼번에 적용할 수 있다.
package ref;
public class Method03 {
public static void main(String[] args) {
Student student1 = new Student();
intiStudent(student1, "학생" , 12 , 78);
//student1.name = "학생";
//student1.age = 12;
//student1.grade = 78;
Student student2 = new Student();
initStudent(student2, "학생2" , 11 , 98);
// student2.name = "학생2";
// student2.age = 11;
// student2.grade = 90;
printStudent(student1);
printStudent(student2);
//1번의 참조값을 받아서 아래의 'printstudent'에게 값을 넘길 것이다.
}
static void intiStudent(Student student, String name, int age, int grade) {
student.name = name;
student.age = age;
student.grade = grade;
//인스턴스에서 넘어온 매게변수를 대입해준다.
}
}
- initStudent(Student student, ...)` : 전달한 학생 객체의 필드에 값을 설정한다. `
- printStudent(Student student, ...)` : 전달한 학생 객체의 필드 값을 읽어서 출력한다.
더 나아가서
Student student1 = new Student();
printStudent(student1, "학생" , 12 , 78);
Student student2 = new Student();
printStudent(student2, "학생2" , 11 , 98);
이렇게 중복으로 적는 것도 안하고 싶다.! 그럼 어떻게 해야할까..
package ref;
import static ref.Method03.printStudent;
public class Method04 {
public static void main(String[] args) {
Student student1 = createStudent("학생" , 12 , 78);
Student student2 = createStudent( "학생2", 11, 98);
// Student student1 = new Student();
//printStudent(student1, "학생" , 12 , 78);
//Student student2 = new Student();
//printStudent(student2, "학생2" , 11 , 98);
// student2.name = "학생2";
// student2.age = 11;
// student2.grade = 90;
printStudent(student1);
printStudent(student2);
//1번의 참조값을 받아서 아래의 'printstudent'에게 값을 넘길 것이다.
}
static Student createStudent(String name, int age, int grade) {
Student student = new Student();
//객체 생성을 여기서 진행 한다.
student.name = name;
student.age = age;
student.grade = grade;
return student;
//return 을 사용하여 참조값을 전부 생성 완료 하였다.
//그럼 맨위의 메서드를 호출하여
}
static void printStudent(Student student) {
System.out.println("이름:" + student.name + " 나이:" + student.age + " 성적:" + student.grade);
}
}
위에 짠 순서를 보면,
1. createStudent 메서드 생성
2. 메서드 안에 클래스의 student 객체 생성
3. return 으로 인해 다시 맨 위의 객체 참조값을 받음
4. 아래의 printStudent 메서드를 값을 받아 Student 클래스에 있는 객체들의 참조값을 전부 출력