java

자바의 static 과 final

하루이2222 2024. 7. 28. 19:30

final

코드

public class FinalExam {
    private final String message = "Final Message"; // (1)

    public FinalExam() {
        this.message = "Final Message~"; // (3)
        // Variable 'message' might already have been assigned to
    }

    public final void showMessage() {
        System.out.println(message);
    }

    public void showMessage(final String message) {
        // message = "New Message!";
        // Cannot assign a value to final variable 'message'
        System.out.println(message);
    }
}

final의 역할

  1. (1) private final String message = "Final Message";:

    • 클래스 필드인 messagefinal로 선언되어 있다.
    • 이로 인해 message 필드는 한 번 초기화된 후 변경될 수 없다.
    • 여기서 초기화는 필드 선언과 동시에 이루어지며, "Final Message"로 설정된다.
  2. (3) this.message = "Final Message~";:

    • 생성자 내부에서 this.message에 값을 다시 할당하려고 시도한다.
    • final 필드는 초기화 이후 값을 변경할 수 없으므로, 이 시도는 컴파일 오류를 발생시킨다.
    • 따라서, 생성자에서 final 필드를 초기화하려면 필드 선언 시 초기화를 생략해야 한다.
  3. public final void showMessage():

    • 이 메서드는 final로 선언되어 있다.
    • 메서드가 final로 선언되면, 이 메서드는 서브클래스에서 오버라이드할 수 없다.
    • 즉, 이 메서드의 구현은 변경되지 않으며, 상속받은 클래스에서 그대로 사용된다.
  4. public void showMessage(final String message):

    • 메서드 매개변수 messagefinal로 선언되어 있다.
    • final 매개변수는 메서드 내부에서 값을 변경할 수 없다.
    • 따라서, message 매개변수에 새로운 값을 할당하려는 시도는 컴파일 오류를 발생시킨다.

정리

  • final 필드:

    • 한 번 초기화된 후 변경할 수 없는 필드.
    • 초기화는 선언 시점이나 생성자에서 한 번만 가능하다.
  • final 메서드:

    • 서브클래스에서 오버라이드할 수 없는 메서드.
    • 메서드의 구현이 변경되지 않도록 보장한다.
  • final 매개변수:

    • 메서드 내부에서 값을 변경할 수 없는 매개변수.
    • 메서드 내에서 매개변수의 값을 보호한다.

static

static 키워드와 정적 필드

  • 정적 필드 (static field):
    • static 키워드가 적용된 필드를 정적 필드 또는 클래스 변수라고 한다.
    • 정적 필드는 해당 클래스의 모든 인스턴스 객체들이 공유하는 변수이다.
    • 정적 필드는 객체의 인스턴스화(생성) 없이 클래스 이름으로 정적 필드에 접근할 수 있다.
    • 해당 정적 필드의 접근지정자가 무엇인지에 따라 접근 방식에 차이가 있다.

예제 코드 설명

Student 클래스

public class Student {
    private static int nextId = 1; // 정적 필드
    private int id; // 인스턴스 필드

    public void setId() {
        id = nextId;
        nextId++;
    }

    public int getId() {
        return id;
    }

    public int getNextId() {
        return nextId;
    }
}
  • nextId 필드는 static 키워드를 사용하여 정적 필드로 선언되었다. 모든 Student 객체는 이 필드를 공유한다.
  • id 필드는 인스턴스 필드로, 각 Student 객체마다 고유한 값을 가진다.
  • setId 메서드는 nextId 값을 id에 할당하고, nextId 값을 증가시킨다.
  • getId 메서드는 인스턴스 필드 id 값을 반환한다.
  • getNextId 메서드는 정적 필드 nextId 값을 반환한다.

main 메서드

public static void main(String[] args) {
    Student minsu = new Student();
    Student heejin = new Student();
    Student sumi = new Student();
    Student yoon = new Student();

    minsu.setId();
    System.out.println(minsu.getNextId()); // 2

    heejin.setId();
    System.out.println(heejin.getNextId()); // 3

    sumi.setId();
    System.out.println(sumi.getNextId()); // 4

    yoon.setId();
    System.out.println(yoon.getNextId()); // 5
}
  • main 메서드에서 네 개의 Student 객체를 생성한다: minsu, heejin, sumi, yoon.
  • 각 객체에 대해 setId 메서드를 호출하면, nextId 값을 id에 할당하고 nextId 값을 증가시킨다.
  • getNextId 메서드를 호출하여 현재 nextId 값을 출력한다. 출력 결과는 다음과 같다:
    • minsu.setId()nextId 값은 2.
    • heejin.setId()nextId 값은 3.
    • sumi.setId()nextId 값은 4.
    • yoon.setId()nextId 값은 5.

요약

  • 정적 필드:
    • 모든 인스턴스가 공유하는 클래스 변수.
    • 클래스 이름으로 접근 가능.
  • 인스턴스 필드:
    • 각 인스턴스마다 고유한 변수.
    • 객체 생성 후 객체 참조를 통해 접근.
  • 메서드 호출과 필드 변경:
    • setId 메서드를 호출하면, nextId 값이 각 객체의 id에 할당되고, nextId 값이 증가한다.