Java

Java) final 키워드

김코식 2022. 12. 17. 03:18

final이란


final 키워드를 붙이면 시간이 지나도 처음 정의된 상태가 변하지 않는 것을 보장한다는 의미로

 

변수, 메서드 , 클래스에 사용가능하고 어느곳에 사용 되는지에 따라 다른 의미를 가진다.

final 키워드는 사실 있으나 없으나 기능이 동작하는데는 문제가 발생하지 않는다.

하지만 추후 유지보수를 생각하면 사용하는게 좋다.

 


변수에 붙을 경우

final이 변수에 붙을 경우 수정 할 수없는 상태의 변수로 정의된다.

만약 객체안의 변수라면 생성자나 static 을 통한 초기화는 허용된다.

 

수정할 수 없는 범위는 final이 붙은 변수의 값에 한정한다. 즉, 다른 객체를 참조할 때는 참조하는 객체의 내부의 값을 변경할수 있다.

public class Animal {

    public static void main(String[] args) {
        final int value = 20;
        final Person person= new Person("김인광",25);

        System.out.println(person.getAge());
        System.out.println(person.getName());


        person.setAge(5);
        person.setName("인광");

        System.out.println(person.getAge());
        System.out.println(person.getName());


     /*   value=2; // 컴파일 에러
        person =new Person("이상현",29); // 컴파일 에러*/
    }
}
class Person{
    private String name;
    private int age;

    public Person(String name , int age){
        this.name = name;
        this.age = age;

    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

final로 선언한 변수를 초기화 전에 사용하면 컴파일 에러 발생

 

메서드 내부 변수

 - 선언시 초기화

 - 사용 전 초기화

 

public void Person(){
    final int age = 10;         //선언시 초기화
    final int age2 ;

    System.out.println(age);  
    System.out.println(age2);   //초기화 하지 않고 사용시 컴파일 에러
    
    age2 =1;                    // 사용 전 초기화
    System.out.println(age2);
}

 

객체 맴버 변수

 - 선언시 초기화

 - 생성자로 초기화

 - 초기화 block으로 초기화

public class Animal {

    private final String type = "강아지";   // 선언시 초기화
    private final String name;

    private final int age;
    {                                       // 초기화 block을 이용한 초기화
        age = 2;
    }
    
    public Animal(String name){             // 생성자를 이용한 초기화
        this.name = name;
    }
    
    
}

 

static 변수

 - 선언시 초기화

 - static 초기화 block으로 초기화

 

public class Animal {

    private static final String name = "나비";
    private static final int age;
    static {
        age = 2;
    }
    
}

메서드에 붙을 경우

final이 메서드에 붙이면 override를 제한한다.

클래스에 상속되면 우리는 해당 클래스의 protected, public등의 접근 제어자를 가진 메서드를 상속받아 재구현 할 수 있다.

즉, 동일한 메서드지만 다르게 동작이 가능

public class Animal {

    public void m1(){

    }
    public static void m2(){ // 상속받는 클래스에서 메서드 오버라이딩 불가능

    }
}
class Person extends Animal{
    public void m1(){

    }

    public void m2(){   // 상속받은 메서드 수정 불가

    }
}

 


클래스에 붙을 경우

final 키워드를 클래스에 붙이면 상속 불가능 클래스로 정의

즉 , 다른 클래스에서 상속하여 재정의를 할 수 없다.

대표적인 클래스로는 Integer , Wrapper 클래스 등이 있음

재정의 여부를 생각하여 재정의 불가능으로 등록시 유지보수에 용이

public final class Animal {

}
class Person extends Animal{        //상속 불가능

}

static + final = static final?

final은 변수, 메소드 , 클래스등을 정의한 뒤 변경하지 못하게 할 때 사용

static은 객체 생성 없이 사용할 수 있는 필드와 메소드를 생성할 때 사용

 

static final은 상수를 선언할 때 사용

ex) 

private static final String ADMIN_TOKEN = "AAABnvxRVklrnYxKZ0aHgTBcXukeZygoC";

static + final로 ADMIN_TOKEN은 불변의 값을 가지고

해당 값은 객쳄마다 저장 될 필요가 없고(static) 여러 값을 가질 수 없다(final)

 

 


 

참고자료 

https://sabarada.tistory.com/148

https://makemethink.tistory.com/184