이번 포스팅에서는 제어자 중 하나인 final에 대해 끄적여 보겠습니다.

final이 무슨뜻일까요?

최종의, 마지막의.. 뭐 이런 뜻 아닌가요? ㅎ

final 제어자는 변수, 메소드, 클래스에 사용 할 수 있습니다.


final을 변수에 사용하게 되면 변경 할 수 없는 상수가 됩니다.

final을 메소드에 사용하면 재정의 할 수 없는 메소드 즉, 오버라이딩을 통해 재정의 되지 못하는 메소드가 됩니다.

final을 클래스에 사용하면 변경 할 수 없는 클래스, 상속을 할 수가 없는 클래스가 됩니다.


한마디로 final을 붙이면 맘대로 건드리지 못한다는 거죠.

변수, 메소드, 클래스에 각각 final을 사용하여 맛을 보도록 하겠습니다.


먼저 final변수에 대해 알아보겠습니다.

FinalCheck.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.dreamstorage.modifier;
 
public class FinalCheck {
    
    static final String name = "Sogom";
    
    public static void main(String[] args) {
        
        name = "소곰";    // 에러발생        
        System.out.println(name);
    }
    
    
}
cs

위의 소스와 같이 final이 붙은 멤버변수를 "소곰" 이라고 바꾸려고 하니 에러가 발생합니다.

이렇게 final을 사용한  변수의 경우는 최초 한번만 값을 초기화 시키고 그 다음은 값을 바꿀 수가 없습니다.

위의 소스와 같이 선언과 동시에 초기화를 하는 방법도 있지만 인스턴스변수의 경우라면 생성자에서 초기화를 시킬수도 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.dreamstorage.modifier;
 
public class FinalCheck {
    
    //static final name;
    final String Name;
    final int Age;
    
    FinalCheck(String name, int age){
        this.Name = name;
        this.Age = age;
    }
    
    public static void main(String[] args) {
        
        //name = "소곰";    에러발생
        //System.out.println(name);
        
        FinalCheck fc = new FinalCheck("Sogom",26);
        System.out.println("이름 : " + fc.Name);
        System.out.println("나이 : " + fc.Age);
    }    
}


cs

위의 소스와 같이 생성자를 만들어 초기화를 시켜주면 final이 붙은 멤버변수가 다른 값을 가질 수 있도록 하는 것이 가능하겠죠?


이번엔 final클래스를 알아보겠습니다.

제가 위에서 final클래스는 상속을 할 수가 없다고 했는데요

조금 더 자세하게 말하면 final클래스는 부모클래스가 될 수는 없지만, 자식클래스는 될 수가 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.dreamstorage.modifier;
 
final class FinalTest{
    private int var;
 
    public int getVar() {
        return var;
    }
 
    public void setVar(int var) {
        this.var = var;
    }
    
}
 
public class FinalCheck_Class extends FinalTest{    //에러발생!!
    public static void main(String[] args) {
        FinalCheck_Class fc = new FinalCheck_Class();
        fc.setVar(10);
        System.out.println(fc.getVar());
    }
}
 
cs

위에서 말했듯 final이 붙은 FinalTest클래스는 조상클래스가 될 수 없기 때문에 에러가 발생할겁니다.

이클립스는 The type FinalCheck_Class cannot subclass the final class FinalTest 와 같은 에러메시지를 띄울거에요.

(FinalCheck_Class클래스는 final클래스인 FinalText클래스가 될수 없다는 내용입니다.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.dreamstorage.modifier;
 
class FinalTest{
    private int var;
 
    public int getVar() {
        return var;
    }
 
    public void setVar(int var) {
        this.var = var;
    }
    
}
 
final class FinalTestDemo extends FinalTest{
    
}
 
public class FinalCheck_Class{
    public static void main(String[] args){
        FinalTestDemo ftd = new FinalTestDemo();
        ftd.setVar(5);
        System.out.println(ftd.getVar());
    }
}
cs

위의 소스에서는 final클래스인 FinalTestDemo클래스가 FinalTest클래스를 상속하고 있습니다.

이 소스는 에러없이 실행이 됩니다.

왜? final클래스는 조상클래스는 될 수는 없지만 자손클래스는 될 수 있기 때문에~


이번에는 final메소드의 경우입니다.

FinalCheck_Method.java

1
2
3
4
5
6
7
8
9
10
11
12
package com.dreamstorage.modifier;
 
class FinalTest_Method{
    public final void hello(){
        System.out.println("Hello");
    }
}
public class FinalCheck_Method extends FinalTest_Method {
    public final void hello(){    //에러발생
        System.out.println("하이~");
    }
}
cs

FinalTest_Method클래스에 만든 hello()를 FinalCheck_Method클래스에서 재정의(오버라이딩)하려고 했습니다.

그러나 hello()가 final인 관계로 불가능하네요.

이클립스는 Cannot override the final method from FinalTest_Method 와 같은 문구를 보여주기도 하네요.

(FinalTest_Method로부터 final메소드를 재정의 할 수 없다는 내용입니다)

오버라이딩에 대해서 잘 모르신다면

java의 17번째 포스팅을 참고해주세요

[Java] 17. 오버라이딩(Overriding)


이렇게 final에 대해서 알아 보았습니다~