心有多大舞臺(tái)便有多大

          Embrace changes, pursue excellence, share niceness.

          通過反射修改類的私有字段值,調(diào)用私有方法

          下面這個(gè)例子在實(shí)際項(xiàng)目中一般都不會(huì)這么用,只是用來說明怎么通過反射修改類的私有字段的值.

          有一個(gè)類TestData:

          public class TestData {
           private String name = "1";
           
           public String getName() {
            return name;
           }
          }
          在運(yùn)行的時(shí)候怎么來修改name的值呢?

          public class TestReflection extends TestCase {
           public void testSetPrivateField() throws Exception {
            TestData data = new TestData();
            System.out.println(data.getName());
            Assert.assertEquals("1", data.getName());
            Field f = data.getClass().getDeclaredField("name");
            f.setAccessible(true);
            f.set(data, "2");
            System.out.println(data.getName());
            Assert.assertEquals("2", data.getName());
           }
          }
          運(yùn)行結(jié)果:
          1
          2
          其中,最關(guān)鍵的代碼是:
          f.setAccessible(true);
          這行代碼把對象data上的name字段設(shè)置為public訪問屬性.

          既然私有字段可以這樣訪問,那么,類似的,私有方法也可以這樣調(diào)用!
          改一下TestData:

          public class TestData {
           private String name = "1";
           
           public String getName() {
            return name;
           }
           
           private void setName(String name) {
            this.name = name;
           }
          }
          在TestData中增加了私有的setName方法,下面是測試代碼:
          public class TestReflection extends TestCase { 
           public void testInvokePrivateMethod() throws Exception {
            TestData data = new TestData();
            System.out.println(data.getName());
            Assert.assertEquals("1", data.getName());
            Method m = data.getClass().getDeclaredMethod("setName", String.class);
            m.setAccessible(true);
            m.invoke(data, "3");
            System.out.println(data.getName());
            Assert.assertEquals("3", data.getName());
           }
          }
          運(yùn)行結(jié)果:
          1
          3
          其中最關(guān)鍵的代碼行是:
          m.setAccessible(true);
          它把對象data的setName方法的訪問屬性設(shè)置為public.

          那么這樣調(diào)用私有方法,訪問私有屬性有什么用處呢?
          在實(shí)際項(xiàng)目中,我們會(huì)使用很多其它第三方的包,有的時(shí)候是通過修改源代碼完成你想要的功能,有的時(shí)候,是因?yàn)榈谌桨袃H僅因?yàn)槟硯讉€(gè)方法的訪問屬性被設(shè)置為private,或者只要修改private的字段值即可.這個(gè)時(shí)候,用這種反射的方法就可以很容易實(shí)現(xiàn)了.

          另外一個(gè)場景就是從系統(tǒng)架構(gòu)層來考慮數(shù)據(jù)封裝.例如系統(tǒng)有一些元數(shù)據(jù)類,99%的情況下,我們只是提供get方法供其它應(yīng)用層獲得字段的值,如果把修改的set方法也提供出去,那么可能會(huì)影響到系統(tǒng)的可維護(hù)性.而在系統(tǒng)運(yùn)行期間,又很難避免的要修改這些元數(shù)據(jù)的值.這種情況下,也可以通過這種反射的方式來實(shí)現(xiàn).

          posted on 2008-06-19 10:14 pony 閱讀(3341) 評論(1)  編輯  收藏 所屬分類: Java

          評論

          # re: 通過反射修改類的私有字段值,調(diào)用私有方法 2008-06-20 08:38 Matthew Chen

          轉(zhuǎn)載了,謝謝。
          http://blog.csdn.net/djsl6071/archive/2008/06/20/2567918.aspx  回復(fù)  更多評論   

          主站蜘蛛池模板: 加查县| 济阳县| 永丰县| 吉隆县| 和田县| 嵊泗县| 准格尔旗| 三原县| 奉贤区| 武山县| 苍山县| 宜良县| 曲麻莱县| 哈尔滨市| 什邡市| 咸阳市| 镇坪县| 陵川县| 土默特右旗| 晋江市| 东辽县| 陇南市| 南和县| 陵川县| 新兴县| 丰顺县| 曲沃县| 五峰| 镇康县| 陕西省| 闽清县| 新源县| 姜堰市| 五峰| 九台市| 祁阳县| 中超| 益阳市| 泽普县| 连城县| 电白县|