Programing Language/JAVA

Effective Final과 lambda expression의 Scope

칼쵸쵸 2020. 8. 16. 23:07

Effective Final : 메서드 안에 정의 된 필드 값으로 Final이 선언되지 않았지만 사실상 변수를 변경하는 부분이 없는 변수

 

예제

public static void main(String[] args) {
	
}

public void run()
{
	int num = 10; //effective Final
	
	//로컬 클래스
	class local
	{
		void print()
		{
			int num=11;
			System.out.println("hi");
		}
	}
	
	//익명 클래스
	Consumer<Integer> anomy = new Consumer<Integer>() {
		
		@Override
		public void accept(Integer t) {
			int num=11;
			System.out.println("hi");
		}
	};
	
	//람다식
	Consumer<Integer> lamda = (num) ->
	{
		//int num=11;
		System.out.println("hi");
	};
    
    //num++;
}

 

위의 예제에서 확인 하듯 num이라는 변수는 메서드 run() 안에서 정의된 변수이다.

num은 내부의 어떤 변화를 가지고 있지 않으므로 Effective final 변수이다.

 

 

 

변수 Scope

첫번째로 구현된것은 로컬 클래스이다.

Scope를 보면 run() 메서드와 다르다. 따라서 num 이라는 이름의 변수를 다시 선언 할 수 있으며 해당 클래스를 생성하여 실행하게 되면 메서드 안에 정의된 num 이 아닌 로컬 클래스 안의 num이 사용되게 된다.

 

이렇게 외부변수가 내부에서 같은 이름의 변수에 가려지게 되는것을 Shadowing이라고 한다.

 

 

두번째로 구현된 익명 클래스도 마찬가지로 run() 과 Scope가 다르다.

따라서 익명 클래스의 내부에 생성된 num변수 또한 run()num을 가리고 익명 클래스의 num을 사용한다.

 

 

세번째로 구현된 Lamda 식은 run과 Scope가 같다.

람다식 내에서 num을 다시 정의 하는것은 같은 이름의 변수를 선언하는것과 마찬가지 이므로 컴파일 오류를 일으키게 된다.

이는 람다식의 파라미터 (num) -> ... 을 실행하는 부분에서도 사용되어서는 안되며 내부동작에서 num을 변경하는 행위도 불가 하다.

 

 

Lamda 와 Effective Final

람다식 안에서 num 변경하지 않고 사용할 수 있다. 이는 run메서드의 num 변수가 사용된것이다.

그러나 람다식을 통해 num 변수를 사용하게 된 경우 num은 Effective Final이어야 한다.

 

Effective Final의 경우 사실상 변수를 변경하는 부분이 없는 부분이어야 하므로 람다식 밖에서 num을 변경하는 부분 또한 불가하다.

람다식에서 사용하는 모든 변수는 외부의 값을 바꿀 수 없으며 이는 람다식이 수학적 함수식이기 때문이다.