咖啡伴侶

          呆在上海
          posts - 163, comments - 156, trackbacks - 0, articles - 2

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

          有一個(gè)類TestData:

          public class TestData {
          ?private String name = "1";
          ?
          ?public String getName() {
          ??return name;
          ?}
          }
          在運(yùn)行的時(shí)候怎么來(lái)修改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);
          這行代碼把對(duì)象data上的name字段設(shè)置為public訪問(wèn)屬性.

          既然私有字段可以這樣訪問(wèn),那么,類似的,私有方法也可以這樣調(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方法,下面是測(cè)試代碼:
          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);
          它把對(duì)象data的setName方法的訪問(wèn)屬性設(shè)置為public.

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

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

          主站蜘蛛池模板: 盐池县| 宕昌县| 平凉市| 镇坪县| 东宁县| 察雅县| 清原| 忻州市| 天祝| 陕西省| 岳池县| 桑植县| 绍兴县| 泰宁县| 慈溪市| 云霄县| 涞水县| 金沙县| 临清市| 台北市| 砀山县| 梁河县| 桐庐县| 桂林市| 门源| 商都县| 罗源县| 漳平市| 苍梧县| 禄丰县| 图木舒克市| 巴南区| 府谷县| 乳源| 康乐县| 黄冈市| 桃园市| 威远县| 南澳县| 霍林郭勒市| 闵行区|