Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Method Local Inner Class เข้าถึง Local Final Variables ได้ไหม?

ได้ Method Local Inner Class สามารถเข้าถึง Local Final Variables (หรือ Effectively Final ใน Java 8+) ได้ เพราะ Final Variables เก็บอยู่ใน Heap และมีอายุยืนยาวพอสำหรับ Inner Class Object

Method Local Inner Class

  • ประกาศ ภายใน Method (Local Scope)
  • Instance ส่งเป็น Argument/Return จาก Method ได้
  • ข้อจำกัด: เข้าถึง Local Variable ได้ก็ต่อเมื่อเป็น final (Java 7) หรือ Effectively Final (Java 8+ - ไม่ถูก Reassign)
  • Method สิ้นสุดแล้ว Local Variables ปกติจะหายไป แต่ Final Variables คงค่าไว้ให้ Inner Class

ตัวอย่างโค้ด


class MainClassTest {
    private int x = 10;  // Instance Variable
    
    public void sampleMethod() {
        final int y = 20;  // Local Final Variable
        
        // Method Local Inner Class
        class MethodLocalInnerClassTest {
            public void accessMainClassVar() {
                System.out.println(x);  // เข้าถึง Outer Instance Variable ได้
                System.out.println(y);  // เข้าถึง Local Final Variable ได้
            }
        }
        
        MethodLocalInnerClassTest mainTest = new MethodLocalInnerClassTest();
        mainTest.accessMainClassVar();
    }
}

public class Test {
    public static void main(String args[]) {
        MainClassTest test = new MainClassTest();
        test.sampleMethod();
    }
}

ผลลัพธ์


10
20

Effectively Final (Java 8+)

ไม่ต้องเขียน final ก็ได้ ถ้าตัวแปร ไม่ถูก Reassign หลัง Initialize


public void sampleMethod() {
    int y = 20;  // ไม่มี final แต่ Effectively Final
    // y = 30;  // ถ้า Uncomment → ไม่ Effectively Final → Compile Error ใน Inner Class
    
    class Inner {
        void print() { System.out.println(y); } // OK
    }
}

ทำไมต้อง Final/Effectively Final?

  • Local Variables เก็บใน Stack Frame ของ Method หายไปตอน Method Return
  • Inner Class Object อาจมีอายุยาวกว่า Method (Return กลับไปใช้ต่อ)
  • Final → ค่าคงที่ → Compiler สร้าง Copy ของค่า ใส่ใน Inner Class Instance (Heap)
  • Non-Final → ค่าเปลี่ยนได้ → ไม่สามารถ Copy ได้ปลอดภัย → Compile Error

กรณี Non-Final Variable


// Workaround: Copy to Final Variable
public void sampleMethod() {
    int nonFinal = 10;
    nonFinal = 20;  // Changed
    
    final int copy = nonFinal;  // Copy ค่าสุดท้าย
    
    class Inner {
        void print() { System.out.println(copy); } // OK
    }
}

สรุป Scope การเข้าถึง

Variable TypeAccessible in Method Local Inner Class?
Outer Instance Variable✅ Yes (ผ่าน Outer.this)
Outer Static Variable✅ Yes
Method Parameter (Final/Effectively Final)✅ Yes
Local Variable (Final/Effectively Final)✅ Yes
Local Variable (Non-Final, Reassigned)❌ No (Compile Error)