Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Everything has an expiration date

123 - Java 중첩 클래스 : (메소드 내부) 지역 중첩 클래스 본문

[Java]/Program source (java)

123 - Java 중첩 클래스 : (메소드 내부) 지역 중첩 클래스

Jelly-fish 2023. 9. 14. 17:26
메소드 내부의 지역(Local) 중첩 클래스를 사용할 때 주의할 사항

 

outer 클래스의 write() 메소드가 실행될 때만 사용할 수 있는 inner 클래스 (LocalTest)

이때, outer 클래스 write() 메소드 내부지역변수 `final int c = 20;`와, `int d = 40;`를 선언하고

inner 클래스write() 메소드에서 d를 출력하려 하면 오류가 발생한다.

 

outer wirte() 메소드 내부의 지역변수 d의 값을 변동시키면(sum)

메소드가 어디서, 언제 호출될지에 따라 d 값이 변화하기 때문에 

값이 불안정해진다. 

 

따라서, inner 클래스write() 메소드에서 d를 출력하려고 하면...

Java에서 불안정한 값의 출력을 막기 위해서 접근을 막는 것이다!

//outer
class Test2
{
	static int a = 10;
	int b = 20;

	void write()									//-- 첫 번째 write() 메소드
	{
		System.out.println("write()...①");
		final int c = 20;
		int d = 40;
		
		// inner
		class LocalTest
		{
			void write()							//-- 두 번째 write() 메소드
			{
				System.out.println("write()...②");
				System.out.println("a : " + a);		
				System.out.println("b : " + b);		
				System.out.println("c : " + c);		
				System.out.println("d : " + d);	// ← Error !!

			}
		}
		d+=10;	// ← check!!!

	
		LocalTest lt = new LocalTest();												
    	lt.write();						// 메소드 내부에서 LocalTest의 write() 메소드가
                                        // 언제 어디서 호출될지 모르기 때문에
                                        // d의 값을 변화하는 과정에서 값에 불안정함이 생긴다!

                                        // 즉, 출력하는 과정에서...
                                        // 『 d의 값은 어떤 값이라고 확신할 수가 없다. 』
                                        // c의 경우 final 정수이기 때문에
                                        // 어디서 메소드를 호출하든 항상 고정된 값 20이므로
                                        // 출력이 가능한 것이다!
                                        
		d+=20;	// ← check!!!
        
	}
}

 

/*==============================
  ■■■ 클래스 고급 ■■■
  - 중첩 클래스
================================*/


//outer
class Test2
{
	static int a = 10;
	int b = 20;

	void write()									//-- 첫 번째 write() 메소드
	{
		System.out.println("write()...①");
		final int c = 20;	// 『 final 』 : 얼마의 시간이 지나든, 인스턴스가 언제 생성되든 고정된 값 20 그대로!!!!
		int d = 40;
		
		// inner
		// 메소드 안에 존재하는 또다른 클래스(로컬 클래스, local class, 지역 클래스)
		class LocalTest
		{
			void write()							//-- 두 번째 write() 메소드
			{
				System.out.println("write()...②");
				System.out.println("a : " + a);		//-- 가장 먼저 태어난 static OK!
				System.out.println("b : " + b);		//-- 인스턴스 변수, 인스턴스 클래스 (생성시점 동일!) OK!
				System.out.println("c : " + c);		//-- 고정된 값이므로 
				//System.out.println("d : " + d);	//-- d는 LocalTest 인스턴스가 언제 선언되느냐에 따라 값이 달라짐(불안정!) X!

			}
		}

		// ※ 변수 c 와 변수 d 는 둘 다 지역변수이지만...
		//    (첫 번째 write() 메소드 안에서 선언된 변수이므로...)
		//    c 는 final 변수이기 때문에
		//    두 번째 write() 메소드에서 언제 접근하더라도
		//    고정된 값 20이 담겨있음을 보장받을 수 있다.
		//    반면에 d 는 그 값이 수시로 변화될 수 있는 상황이므로
		//    LocalTest 클래스의 인스턴스 생성 시점이
		//    언제가 될지 알 수 없기 때문에
		//    이로 인해 인스턴스 생성 시점에 d 에 어떤 값이 담겨있는지를
		//    보장받을 수 없게 된다.
		//    변수 d 에 접근하는 것은 피할 수 있도록 문법적으로 처리하는 것이다.

		//d+=10;
		d++;

		// LocalTest 클래스 기반 인스턴스 생성(→ inner)
		LocalTest lt = new LocalTest();				//-- 따로 독립적으로 인스턴스 생성해야 LocalTest 탄생!
													//   태어날지 안 태어날지를 확실히 할 수 없다.
													//   인스턴스 생성시점을 보장받지 못함...
													//   안정적이지 못하기 때문에 d에 접근 불가.
													//   인스턴스를 언제 생성하느냐에 따라 달라진다...
													//   인스턴스를 언제 생성할지에 따라 d의 값이
		lt.write();									//-- 두 번째 write() 메소드 호출


		d+=20;
	}
}

public class Test123
{
	public static void main(String[] args)
	{
		// Test2 클래스 기반 인스턴스 생성(→ outer)
		Test2 ob = new Test2();
		ob.write();									//-- 첫 번째 write() 메소드 호출 
	}
}