Menu
CoddyTech

final 키워드

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 87개 중 13번째.

Java의 final 키워드는 수정을 방지합니다. 변수, 메서드, 클래스에 적용할 수 있으며, 각각 다른 효과가 있습니다.

변수에 적용하면 final은 해당 변수를 상수로 만듭니다. 한 번 할당되면 값을 변경할 수 없습니다.

public class Circle {
    private final double PI = 3.14159;
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;  // constructor에서 한 번 할당할 수 있음
    }
    
    public void setRadius(double r) {
        // this.radius = r;  // 오류! final 변수에는 다시 할당할 수 없음
    }
}

final 변수는 선언 시 또는 생성자에서 초기화해야 합니다. 그 이후에 다시 할당하려고 하면 컴파일 오류가 발생합니다.

참조 타입에서 final은 참조가 다른 객체를 가리킬 수 없다는 뜻이지만, 객체의 내용은 여전히 변경할 수 있습니다.

private final StringBuilder name = new StringBuilder("John");

// name = new StringBuilder("Jane");  // 오류! 재할당할 수 없음
name.append(" Doe");  // 좋아요! 객체의 내용은 변경할 수 있음

필드에 final을 사용하면 의도를 명확하게 전달할 수 있습니다. 즉, 초기화 후에는 이 값이 절대 변경되어서는 안 된다는 것을 다른 개발자에게 알려 줍니다. 이는 구성 값, ID 또는 객체의 수명 동안 일정하게 유지되어야 하는 모든 데이터에 특히 유용합니다.

final 메서드는 하위 클래스에서 재정의할 수 없습니다.

class Base {
    public final void greet() {
        System.out.println("Hi");
    }
}
class Child extends Base {
    // public void greet() { }  // 오류! greet()는 Base에서 final로 선언됨
}

final 클래스는 전혀 확장할 수 없습니다. String은 final 클래스이므로 어떤 클래스도 이를 확장할 수 없습니다.

final class Config { }
// class MyConfig extends Config { }  // 오류! Config는 final입니다
challenge icon

챌린지

쉬움

학생이 등록된 후 절대 변경되어서는 안 되는 데이터를 보호하기 위해 final 키워드를 사용하는 Student 등록 시스템을 만들어 봅시다.

코드를 구성하기 위해 두 개의 파일을 만듭니다.

  • Student.java: 설정된 후에는 특정 정보가 영구적으로 고정되는 Student 클래스를 만듭니다.
    • final 필드 studentId (String) - 객체 생성 시 할당되며 절대 변경할 수 없습니다
    • final 필드 enrollmentYear (int) - 학생이 등록한 연도로, 이 값도 영구적입니다
    • 일반 private 필드 name (String) - 학생의 이름이 바뀌면 업데이트할 수 있습니다
    • 세 값을 모두 받아 필드를 초기화하는 생성자
    • 학생 ID를 위한 getter getStudentId()
    • 등록 연도를 위한 getter getEnrollmentYear()
    • 이름을 위한 getter getName()와 setter setName()
    • getInfo() 메서드는 다음을 반환합니다: "ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
  • Main.java: Student 객체를 만든 다음 이름을 업데이트하고 정보를 표시합니다. 학생 ID, 초기 이름, 등록 연도, 업데이트할 새 이름의 네 가지 입력을 받습니다. 두 줄을 출력합니다.
    • 이름을 변경하기 전 학생 정보
    • 이름을 변경한 후 학생 정보

입력은 순서대로 네 가지를 받습니다: studentId (String), name (String), enrollmentYear (int), newName (String).

final 필드가 학생의 ID와 등록 연도를 어떻게 보호하는지 확인하세요. 이는 변경되어서는 안 되는 영구 기록인 반면, 이름은 setter를 통해 업데이트할 수 있습니다.

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 입력값 읽기
        String studentId = scanner.nextLine();
        String name = scanner.nextLine();
        int enrollmentYear = scanner.nextInt();
        scanner.nextLine(); // 줄바꿈 문자 소비
        String newName = scanner.nextLine();
        
        // TODO: 초기값으로 Student 객체 생성
        
        // TODO: 이름을 변경하기 전 학생 정보 출력
        
        // TODO: setter를 사용해 학생의 이름 변경
        
        // TODO: 이름을 변경한 후 학생 정보 출력
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Java 컴파일러