본문 바로가기

개발/JAVA

[JAVA] 로컬 클래스에서 final 변수를 사용해야 하는 이유

반응형

로컬 클래스(Local Class)란?

생성자나 메소드 내부에서 선언된 클래스를 말한다.

로컬클래스는 생성자와 메소드가 실행될 동안에만 객체를 생성할 수 있다.

public class A {
	//생성자
	public A() {
    	class B { }	//로컬 클래스
    }
    
    //메소드
    public void method() {
    	class B { }	//로컬 클래스
    }
}

 

 

로컬 클래스 특징은?

생성자나 메소드의 매개변수나 내부에서 선언된 로컬 변수를 로컬 클래스에서 사용할 때는 final 변수를 사용해야 한다.

이러한 로컬 변수는 final 특성을 갖기 때문에 값을 수정할 수 없다.

Java 8 이후부터는 final을 명시하지 않아도 final 변수로 인식이 된다.

물론 그 이전버전에서는 final 키워드를 따로 명시해야 한다.

 

 

그렇다면 왜 로컬 클래스에서 final 변수를 사용해야할까?

로컬 클래스는 외부 클래스의 메소드나 코드 블록 내에서 정의될 수 있다.

로컬 클래스는 해당 메소드나 코드 블록 내에서만 접근이 가능한데 메소드에 선언된 로컬 클래스의 경우 메소드가 실행을 마치고 사라지는 시점에도 계속 사용되는 경우가 있다.

메소드가 끝나면 변수는 사라지지만 로컬 클래스에서 변수를 계속 사용하려면 메소드가 끝나고도 변수에 접근할 수 있어야 한다.

이를 위해서 변수는 final로 선언되어야 한다.

final 변수는 값이 변경될 수 없기 때문에 로컬 클래스에서 안전하게 사용할 수 있다.

그렇게 되면 인스턴스의 안정성과 일관성을 보장할 수 있게 된다.

 

 

메소드 내의 final 변수는 메소드가 종료되면 스택 프레임에서 제거되지 않을까?

메소드가 끝나면 그 안에서 선언된 final 변수를 포함한 해당 메소드의 로컬 변수들은 스택 프레임에서 사라진다.

그렇다면 메소드가 끝나도 이 final로 선언된 변수를 사용하는 원리는 무엇일까?

로컬 클래스가 메소드의 final 변수의 값을 사용하는 방식은 일반 방식과 차이가 있다.

로컬 클래스가 메소드의 final 변수를 직접 참조하는 것이 아닌 final 변수의 값을 로컬 클래스 내부에 복사해두는 방식을 사용한다.

 

 

로컬 클래스가 final 변수의 값을 복사하는 원리?

로컬 클래스가 외부의 변수를 자신의 내부에 저장하는 것을 캡처(capture)라고 한다.

이 때의 final 변수의 값은 로컬 클래스의 인스턴스에 저장된다.

 

 

로컬클래스의 인스턴스를 외부에서 사용하는 방법?

🍟 첫 번째, 리턴하기

로컬 클래스의 메소드가 값을 리턴하는 경우 로컬 클래스의 인스턴스 멤버를 리턴할 수 있다.

메소드가 실행을 끝내면 인스턴스는 외부로 전달되어 다른 코드에서 사용할 수 있다.

🍟 두 번째, 콜백 인터페이스로 전달하기

로컬 클래스의 인스턴스 멤버를 콜백 인터페이스의 구현객체로 전달할 수 있다.

다른 클래스나 메소드에서 인스턴스를 받아서 콜백 메소드를 호출하면서 로컬 클래스의 동작을 실행할 수 있다.

🍟 세 번째, 외부 클래스의 필드로 저장하기

로컬 클래스의 인스턴스를 외부 클래스의 필드에 저장해서 외부에서 접근할 수 있게 한다.

로컬 클래스의 메소드에서 인스턴스를 생성한 후에 외부 클래스의 필드에 할당하면 다른 메소드에서도 그 값을 사용할 수 있다.

🍟 네 번째, 외부 클래스의 메소드에 전달하기

로컬 클래스의 인스턴스를 외부 클래스의 메소드에 전달해서 사용한다.

인스턴스를 메소드의 매개변수로 전달하여 다른 메소드에서 사용할 수 있다.

 

반응형