[JAVA] 김영한의 실전 자바 ; 배열, 기본형과 참조형

선뀰·2023년 12월 22일
0

JAVA

목록 보기
10/25

1. 배열 도입

각각의 학생 별로 객체를 생성하고, 해당 객체에 학생의 데이터를 관리하면 된다.

- 배열 리팩토링

  • 배열 선언 최적화
    생성과 선언을 동시에 하는 경우
    class1[] students = {student1, student2};

  • for문 최적화
    for문을 사용해서 반복 작업을 처리 가능하다.

- 1. 첫번째

for (int i = 0; i<students.length; i++){
            System.out.println("이름 : " + students[i].name + "나이 : " + students[i].age + " 성적 : " + students[i].grade);
        }

- 2. 두번째

for (int i = 0; i<students.length; i++){
            class1 s = students[i];
            System.out.println("이름 : " + s.name + "나이 : " + s.age + " 성적 : " + s.grade);
        }

- 3. 향상된 for문

값을 담아둘 때 향상된 for문을 사용하면 좋다.
iter 단축키

for (class1 s : students) {
            System.out.println("이름 : " + s.name + "나이 : " + s.age + " 성적 : " + s.grade);
        }

2. 기본형과 참조형

변수의 데이터 타입을 크게 보면 기본형과 참조형으로 분류가 가능하다. 값을 변수에 직접 넣을 수 있는 기본형
객체가 저장된 메모리의 위치를 가르키는 참조형으로 분류가 가능하다.

- 기본형

int, long, double, boolean처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입

- 참조형

기본형을 제외한 나머지는 모두 참조형이다.
Student student1, int[] students와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입이다.
객체 또는 배열에 사용된다.

기본형 vs 참조형

기본형은 연산이 가능하지만, 참조형은 연산이 불가능하다.

.을 통해 객체의 기본형 멤버 변수에 접근한 경우 연산이 가능하다.

  • String
    String은 사실 클래스이고, 참조형이다. 하지만 기본형처럼 문자 값을 바로 대입 가능하다.

- 변수 대입

자바는 항상 변수의 값을 복사해서 대입한다.
Student s1 = new Student();

참조형의 경우 객체를 가르키는 참조값만 복사된다.
건물의 위치인 주소만 복사되는 것이다.

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;
}

기본형 일때는 값이 그대로 나오지만, 참조형일땐 값이 변경되어 나온다. dataA.value로 사용할 때

- 기본형과 참조형의 메서드 호출

메서드의 매개변수(파라미터)는 항상 값에 의해 전달된다.
실제 값인가 참조(메모리 주소)값인가에 따라 동작이 달라진다.

  • 기본형
    메서드로 기본형 데이터를 전달하면, 해당 값이 복사되어 전달된다. 이 경우, 메서드 내부에서 파라미터의 값을 변경해도, 호출자의 변수 값에는 영향이 있다.

  • 참조형
    메서드로 참조형 데이터를 전달하면, 참조값이 복사되어 전달된다. 메서드 내부에서 파라미터로 전달된 객체의 멤버 변수를 변경하면, 호출자의 객체도 변경된다.

shift + f6 : rename을 한번에 변경할 수 있다.

package ref;

public class Method1 {
    public static void main(String[] args) {
        Student student1 = new Student();
        initStudent(student1, "학생1", 15, 90);
        //student1.name = "학생1";
        //student1.age = 15;
        //student1.grade = 90;
        
        Student student2 = new Student();
        initStudent(student2, "학생2", 16, 80);
        //student2.name = "학생2";
        //student2.age = 16;
        //student2.grade = 80;

        // 메서드를 만들어서 참조값을 넘겨서 받을 수 있다.
        printStudent(student1);
        printStudent(student2);
    }
    static void initStudent(Student student, String name, int age, int grade){
        student.name = name;
        student.age = age;
        student.grade = grade;
    }
    static void printStudent(Student student) {
        System.out.println("이름 : " + student.name + "나이 : " + student.age + "성적 : " + student.grade);
    }
}

메서드를 호출할 때 참조값을 전달한다. 메서드 내부에서 전달된 참조값을 통해 객체의 값을 변경하거나, 값을 읽어서 사용할 수 있다.

- 메서드에서 객체 반환

Student student1 = new Student();
initStudent(student1, "학생1", 15, 90);

Student student2 = new Student();
initStudent(student2, "학생2", 16, 80);

2번 반복되는 부분을 하나로 합쳐보기

Student student1 = createStudent("학생1", 15, 90);
-> 메서드를 호출 후 결과를 반환
Student student1 = student(x001)
-> 참조형인 student를 반환한다.
Student student1 = x001
-> student의 참조값 대입
student1 = x001이 된다.

- 변수와 초기화

ctrl + B : 변수가 선언된 곳으로 돌아갈 수 있다.

변수의 종류

멤버 변수 : 자동 초기화
인스턴스를 생성할 때 자동으로 초기화된다.
지역 변수 : 수동 초기화
지역 변수는 항상 직접 초기화해야 한다.

null

참조형 변수에는 항상 객체가 있는 위치를 가리키는 참조값이 들어간다. 가리키는 대상이 없거나, 나중에 입력하고 싶다면? null이라는 값을 넣어둘 수 있다.

GC : 아무도 참조하지 않는 인스턴스의 최후

garbage collection 더는 아무도 참조하지 않으면 해당 인스턴스에 접근할 수 있는 방법이 없다. 메모리 용량만 차지할 뿐이다. 아무도 참조하지 않는 인스턴스가 있으면 JVM GC(가비지 컬렉션)이 더이상 사용하지 않는 인스턴스라고 판단 후 자동으로 메모리에서 제거한다.

NullPointerException

null을 가리키다 이다. 이때 발생하는 예외이다. 주소가 없는 곳을 찾아갈 때 발생하는 예외이다.

Data data = null;
data.value = 10; // NullPointerException 예외가 발생하고, 프로그램 종료가 된다.

profile
공부 기록

0개의 댓글