final

황상익·2024년 3월 28일

Inflearn JAVA

목록 보기
19/61

final 변수와 상수 1

final 키워드는 끝!!!
변수에 final 키워드가 붙으면 더이상 값 변경 X

final 지역 변수

public class FinalLocalMain {
    public static void main(String[] args) {
        final int data1;
        data1 = 10;
        //data1 = 20; final은 값은 최초에 한번만 할당 가능

        final int data2 = 20;
        //data2 = 20; X

        method(10);
    }

    static void method(final int parameter){
        //parameter = 20; method = 10으로 이미 할당
    }
}

final을 지역 변수에 설정할 경우 최초에 한번만 할당 가능, 변수 값 변경시 compileError
final 지역 변수 선언시 초기화 한 경우 이미 값 할당
매개변수에 final이 붙으면 메서드 내부에서 매개변수의 값을 변경 X

final - 필드 (멤버 변수)

public class ConstructInit {
    final int val; //final을 필드에 사용할 경우 생성자를 통해 초기화

    public ConstructInit(int val) {
        this.val = val;
    }
}

final을 필드에 사용할 경우 필드는 생성자를 통해 한번만 초기화 가능

public class FieldInit {

    static final int CONST_VALUE= 10;
    final int value = 10;
}

final 필드를 필드에서 초기화시, 이미 값 설정 -> 생성자를 통해서 초기화 X

public class FinalFieldMain {
    public static void main(String[] args) {
        //final 필드 - 생성자 초기화
        System.out.println("생성자 초기화");
        ConstructInit constructInit = new ConstructInit(10);
        ConstructInit constructInit1 = new ConstructInit(20);
        System.out.println(constructInit1.val);
        System.out.println(constructInit.val);

        //필드 초기화 -> 이미 초기화 되어 있기 때문에 변경 불가능
        System.out.println("필드 초기화");
        FieldInit fieldInit = new FieldInit();
        FieldInit fieldInit1 = new FieldInit();
        FieldInit fieldInit2 = new FieldInit();
        System.out.println(fieldInit.value);
        System.out.println(fieldInit1.value);
        System.out.println(fieldInit2.value);

        System.out.println("상수");
        //static 영역
        System.out.println(FieldInit.CONST_VALUE);
    }
}

final 필드를 초기화 하는 경우 각 인스턴스마다 final 필드에 다른 값 할당 가능.
final을 사용 -> 생성 이후에 값을 변경 X

FieldInit과 같이 final 필드를 필드에서 초기화 -> 모든 인스턴스가 다음 오른쪽 그림과 같은 값을 갖는다.
FieldInit 인스턴스의 모든 value == 10
왜냐면 생성자 초기화와 다르게 초기화 필드의 코드에 해당 값은 미리 정해져 있다.
결과적으로 메모리 낭비

static final
FieldInit.My_VALUE는 static 영역에 존재. 그리고 final 키워드를 사용해서 초기화 값 변하지 X
static 영역은 단 하나만 존재. MY_VALUE 변수는 JVM 상에서 하나만 존재.

이런 이유로 final + 필드 초기화 -> static을 앞에 붙여 사용

final 변수와 상수 2

상수
상수는 변하지 X, 일정한 값을 갖는 수. 자바에서 보통 단 하나만 존재하는 변하지 않는 고정된 값을 상수

이런 이유로 상수는 static final 키워드 사용

대문자로 사용, _ 로 구분
필드를 직접 접근해서 사용
-> 상수는 기능이 아니라 고정값 자체
-> 상수는 값을 변경 X

public class Constant {
    //수학
    public static final double PI = 3.14;

    //시간
    public static final int HOUR_IN_DAY = 24;
    public static final int SECONDS_IN_MINUTE = 60;

    //애플리케이션 설정 상수
    public static final int MAX_USERS = 1000;
}

애플리케이션 안에는 당양한 상수 존재.
이런 상수들은 애플리케이션 전반에서 사용 -> public
상수는 중앙에서 값을 하나로 관리
런타임에는 상수 값 변경X

public class ConstMain1 {
    public static void main(String[] args) {
        System.out.println("프로그램 최대 참여자 수 " + 1000);
        int curUserCnt = 999;

        process(curUserCnt++);
        process(curUserCnt++);
        process(curUserCnt++);
    }

    private static void process(int curCnt){
        System.out.println("참여자수 " + curCnt);
        if (curCnt > 1000){
            System.out.println("대기자로 등록 합니다");
        } else {
            System.out.println("게임에 참여 합니다 ");
        }
    }
}
public class ConstMain2 {
    public static void main(String[] args) {
        System.out.println("프로그램 최대 참여자 수 " + Constant.MAX_USERS);
        int curUserCnt = 999;

        process(curUserCnt++);
        process(curUserCnt++);
        process(curUserCnt++);
    }

    private static void process(int curCnt){
        System.out.println("참여자수 " + curCnt);
        if (curCnt > Constant.MAX_USERS){
            System.out.println("대기자로 등록 합니다");
        } else {
            System.out.println("게임에 참여 합니다 ");
        }
    }
}

final 변수와 참조
final은 변수의 값을 변경하지 X, 여기서 변수의 값이란??

변수는 크게 기본형, 참조형 변수

public class Data {
    public int value;
}
public class FinalRefMain {
    public static void main(String[] args) {
        final Data data = new Data();
        //data =new Data(); 참조 대상 변경 불가능

        //참조 대상의 값은 변경 가능
        data.value = 10;
        System.out.println(data.value);
        data.value = 20;
        System.out.println(data.value);

    }
}
    data.value = 10;
        System.out.println(data.value);
        data.value = 20;
        System.out.println(data.value);

참조형 변수에 data에 final이 붙음 -> 변수 선언 시점에 참조값을 할당, 참조값 변경 X
참조형 변수 data에 final이 붙었다. 이경우 참조형 변수에 들어있는 참조값을 다른 값으로 변경X. 다시 말해 다른 객체를 참조 할 수 없다. 참조형 변수에 들어있는 참조값만 변경 X , 이 변수 이외에 다른 곳에 영향을 준다는 의미는 X

public class Member {
    private final Long id;
    private String name;

    public Member(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public void changeData(String name){
        //this.id = id; -> 변경 불가능
        this.name = name;
    }

    public void print(){
        System.out.println("id : " + id + " name : " + name );
    }
}
public class MemberMain {
    public static void main(String[] args) {
        Member member = new Member(1L, "Hwang");
        member.print();
        //member.changeData(2L, "Kim");
        member.changeData( "Kim");
        member.print();
    }
}
profile
개발자를 향해 가는 중입니다~! 항상 겸손

0개의 댓글