본문 바로가기
책벌레와 벌레 그 사이 어딘가/개념쌓기

[개념쌓기] final/ finally/ finalize()

by veganwithbacon 2023. 1. 16.
반응형

final/ finally/ finalize 종종 사용하긴 했지만, 셋의 차이에 대해 명확히 몰랐기에 정리했다.

👀한 눈에 확인하기(para coreanos como yo)

1. final 

변수  : final이 적용된 변수의 값은 초기화 후에는 변경할 수 없다

메소드 : final로 선언된 메서드는 하위 클래스에서 오버라이드 할 수 없다

클래스 : final로 선언된 클래스는 계승 대상이 될 수 없다.(하위 클래스를 만들 수 없다)

 

2. finally

finally 키워드는 try/catch 블록과 함께 사용되며 예외가 던져지더라도 항상 실행될 코드가 지정하기 위해 사용된다

 

3. finalize 

java의 garbage collector는 객체를 삭제하기 전, finalize() 메소드를 호출


  1. final

final 키워드를 사용함으로써 얻을 수 있는 이점

- 개발적 의도(변수, 함수, 클래스의 명시적 제한)

- 코드 가독성 증가

 

final 키워드는 클래스, 메소드, 변수, 인자 선언시에 함께 사용할 수 있다.

final을 사용하면, 기본적인 공통점은 각각의 상태를 유지하려 한다는 점이다.

키워드를 명시하여 한 번만 할당하고 싶을 때 사용

 

1. final 변수

final String hello = "Hello world";
hello = "See you again" //compile error

 위와 같이 final을 사용해 변수를 선언할 수 있다.

final 키워드가 붙은 변수는 한번 초기화하면 그 후는 변경할 수 없다.

만약 변경하려한다면 예시처럼 컴파일 에러가 발생한다.

 

2. final 메소드

부모 클래스의 메소드에 final 키워드를 명시해 자식 클래스의 Override Method의 추가적인 재정의를 막는 의도로 사용

ISP(Interface Segregation Principle)에 따라 추가적인 재정의를 막을 경우에 사용 가능하다.

class AAA{
	final String hello = "alloha";
    
    final String getHello(){
    	return hello;
        }
}

final로 선언된 메소드는, 다른 클래스가 이 클래스를 상속할 때 메소드 오버라이딩을 할 수 없다.

해당 메소드를 상속받는 하위 클래스에서 오버라이딩을 하면 컴파일 에러가 발생한다.

class Child extends Parents{

	@Override
    String getHello(){ //compile error
    	return "its been a long day";
    }
}

 

3. final 클래스

다음 예시처럼 final을 통해 클래스를 정의할 수 있다

final class redefineeClass{
	final String hello1;
    redefineClass(){
    	hello1 = "not hello";
    }
}

final로 클래스를 선언하면, 다른 클래스에서 이 클래스를 상속할 수 없다.

요약에서 말했던 것처럼, final로 선언된 클래스는 계승 대상이 될 수 없다.(하위 클래스 생성 불가)

 

  2. finally

finally는 try-catch와 함께 사용되기에, 필수 블록은 아니다.

try-catch가 종료될 때 finally block이 항상 수행된다. 

finally 블럭은 try 블럭이 종료되는 순간 실행된다. try 블럭 안에 return을 넣더라도 finally 블럭은 try 블록이 종료되는 순간 실행. try 블록은 return/ continue/ break 문을 실행하거나 예외를 던진다거나해도 실행된다.

 

그러나 try-catch 블록 수행 중 VM이 종료되거나

try-catch를 수행하던 쓰레드가 종료되면 finally 블록은 실행되지 않는다.

 

예외 발생 유무와 상관없이 무조건 수행되며, DB 등을 사용한 후 닫는 기능과 같이

항상 수행해야할 필요가 있는 경우 사용된다.

FileInputStream 등의 FileDescriptor를 닫는 경우 사용되기도 한다.

 

3. finalize 

finalize()는 최상위 클래스인 Object 클래스에 선언된 protected 메소드이다.

그렇기에 Java 내의 모든 객체는 finalize() 메소드를 가진다.

 

 GarbageCollector가 어떤 객체를 참조하는 객체가 없다 생각하면, 이 객체를 소멸시킬 때 finalize() 메소드를 호출해준다.

GC가 하는 일이 궁금하다면 다음 글을 참고하도록 하자.

https://veganwithbacon.tistory.com/159

 

[개념쌓기] 가비지컬렉터? JVM에서 힙?

https://veganwithbacon.tistory.com/158 [개념쌓기] 메모리? 스택,힙? 메모리가 무엇을 하는지 알아보고 JAVA 내에서의 메소드 영역의 역할 및 가비지컬렉터의 기능까지 같이 공부할 계획이다. 우선 메모리

veganwithbacon.tistory.com

 

클래스를 정의할 때 finalize()를 오버라이드 할 수 있는데, finalize()는 소멸 시 호출되기에 다른 자원을 함께 소멸시킬 수 있다. 즉, 객체가 삭제되기 직전에 실행되어야 하는 동작이 있다면 Object 클래스에 정의된 finalize() 메소드를 오버라이드 하여 정의할 수 있다.

메소드 호출 시점이 GC에 의존적이기 때문에, 생각한 타이밍과 다를 수 있다. 이 때문에 finalize를 재정의하지 않는 것이 좋다.

반응형

댓글