使用反射調用匿名內部類時應該注意的一些地方


06年寫的

  在使用匿名內部類時,當使用了反射機制來調用其中的方法就會出現訪問異常,這是在前幾天寫程序時遇到的,所以在寫匿名內部類時一定要注意是否在其它地方使用了反射調用。下面給出部份代碼來說明此問題。

public class SuperTest {
    public void hello() {
        System.out.println("Hello from SuperTest");
    }
}


public class Exec {
    public static void run(SuperTest target) {
        System.out.println();

        System.out.print("base class > ");
        run(target, SuperTest.class, "hello");      //1 這里可以正常執行

        System.out.print("obj class  > ");
        run(target, target.getClass(), "hello");    //2 這里可能產生異常
    }


    static void run(Test1 target, Class cls, String method) {
        try {
            cls.getMethod(method, null).invoke(target, null);
        } catch (Exception x) {
            System.out.println(x);
        }
    }
}



public class Test {
    public static void main(String[] args) {
        Exec.run(new SuperTest() {
            public void hello() {
                System.out.println("Hello from Test");
            }
        });
    }
}

 



上面的代碼看似很簡單運行時一般都不會有什么錯誤出現,但是如果將類Test與Exec放在不同包的時候,就會出現異常。因為Exec類無法調用Test中匿名內部類的hello方法導致異常,也許到這里大家都覺得容易理解,但為什么在注釋1的地方可以通過,在注釋2的地方就會出異常呢?這個問題就會使許多朋友開始疑惑了。下面針對該部份內容進行討論學習。
  根據匿名內部類的定義,我們知道:

       

 Exec.run(new SuperTest() {
            public void hello() {
                System.out.println("Hello from Test");
            }
        });

 


的意思是產生一個匿名的class對象,此匿名class繼承自SuperTest類,new后返回一個SuperTest類型的對象。那么為什么注釋2的地方會出異常呢,我們仔細想一下匿名內部類的定義就很清楚了,上面這段代碼可以等同於下面:

Exec.run(new Test().new MySuperTest());
class MySuperTest extends SuperTest {
    public void hello() {
        System.out.println("Hello from Test");
    } 
}

 


  這樣就很容易理解了,在注釋2的地方使用了target.getClass(),而它得到的Class就是MySuperTest,但是此類的修飾符是default的,也就是說在其它包是不能訪問的,所以使用此方法進行調用時會出現異常。雖然容易理解,但開發時經常不注意,常出現類似的問題。

  解決方法當然也是有多種的,呵呵,如果將class MySuperTest加上public修飾符,可以解決此問題,但這樣就不能再使用匿名內部類了,所以也可以將Exec類進行修改,就是在注釋2的地方獲取對象的父類,然后再調用,這樣就可以使用這種結構(但需注意,獲取父類時一定要先判斷是否有所要調用的方法,因為有的並不包含此方法)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM