posts - 495,comments - 227,trackbacks - 0
          http://ljhzzyx.blog.163.com/blog/static/3838031220141011111435161/

          java中,final標識的變量是不可修改的,但是通過反射的方式達到修改的目的。修改的示例也很簡單,在這里 http://stackoverflow.com/questions/2474017/using-reflection-to-change-static-final-file-separatorchar-for-unit-testing
          public class EverythingIsTrue {
              static void setFinalStatic(Field field, Object newValue) throws Exception {
                  field.setAccessible(true);
                  Field modifiersField = Field.class.getDeclaredField("modifiers");
                  modifiersField.setAccessible(true);
                  modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
                  field.set(null, newValue);
              }
              public static void main(String args[]) throws Exception {
                  setFinalStatic(Boolean.class.getField("FALSE"), true);
                  System.out.format("Everything is %s", false); // "Everything is true"
              }
          }
              關鍵點在于.setAccessible(true),并且修改modifiers去除final屬性。獲得修飾符的方式可以通過java.lang.reflect.Modifier,詳細說明在這里
          http://blog.csdn.net/xiao__gui/article/details/8141216
          通過Modifier的isPublic、isPrivate、isStatic等方法,可以判斷是否包含某些修飾符
          boolean isStatic = Modifier.isStatic(field.getModifiers());
          if(isStatic) {
              System.out.println(field.get(null).toString());
          }
          這里的field是靜態類型的,因此field.get(null)方法的參數,可以是null,也可以是A.class這樣的目標類,不用提供實例對象。查看java.lang.reflect.Modifier的代碼,可以知道對修飾符的定義是通過二進制位來實現的。上面文章中有舉例

          public static,對應的整數就是二進制的:1001,也就是9。如下:

          ……

          native

          transient

          volatile

          synchronized

          final

          static

          protected

          private

          public

           

          0

          0

          0

          0

          0

          1

          0

          0

          1


          源碼中的完整定義如下
          public static final int PUBLIC           = 0x00000001;
          public static final int PRIVATE          = 0x00000002;
          public static final int PROTECTED        = 0x00000004;
          public static final int STATIC           = 0x00000008;
          public static final int FINAL            = 0x00000010;
          public static final int SYNCHRONIZED     = 0x00000020;
          public static final int VOLATILE         = 0x00000040;
          public static final int TRANSIENT        = 0x00000080;
          public static final int NATIVE           = 0x00000100;
          public static final int INTERFACE        = 0x00000200;
          public static final int ABSTRACT         = 0x00000400;
          public static final int STRICT           = 0x00000800;
          根據數值,得到完整的順序是這樣的
          strict,abstract,interface,native,transient,volatile,synchronized,final,static,protected,private,public
                由此就可以了解field.getModifiers() & ~Modifier.FINAL這部分的含義的,先~Modifier.FINAL將final所在的位設置為0,其他所有位設置為1。field.getModifiers() & ~Modifier.FINAL與的操作,就是將field的modifiers屬性修飾符中final給去除掉。
                但是在自己嘗試的過程中,發現一個問題。設置final變量的方法是field.set(),如果在這個方法之前調用了field.get()方法,順序如下面這樣
          field.get(null).toString();
          ...
          field.set(null, newValue);
          這時對final變量的賦值就會報錯,就算.setAccessible(true);也是沒有用的。具體原因尚不清楚,估計需要跟蹤源碼才能查清楚。

                需要注意的是,對于int、long、boolean以及String等基本類型,由于編譯器優化的原因,很多使用常量的地方的值還是原來的數值。如
          if (index > maxFormatRecordsIndex) {
              index  =  maxFormatRecordsIndex;
          }
          maxFormatRecordsIndex為final,則被編譯器改成這樣
          if (index > 100) {
              index = 100;
          }
          System.out.println(Bean.INT_VALUE);
          //編譯時會被優化成下面這樣:
          System.out.println(100);
          所以正常的使用方式還是獲取原來的值,獲得修改后的final常量的值需要用field.get(null)這樣的方式。
                總體來講,改基本類型的final常量的用處還是不大,如果是非基本類型常量,則有實際意義。
          posted on 2016-06-28 17:32 SIMONE 閱讀(1649) 評論(0)  編輯  收藏 所屬分類: JAVA
          主站蜘蛛池模板: 万源市| 历史| 高邮市| 宣武区| 临猗县| 台东县| 梁平县| 鹤壁市| 宜川县| 鹿邑县| 南溪县| 肇源县| 琼结县| 疏勒县| 包头市| 鹿邑县| 临邑县| 贡觉县| 渭源县| 台中县| 大港区| 务川| 保定市| 通渭县| 广河县| 沐川县| 丰顺县| 三门县| 五河县| 台东县| 望谟县| 开封县| 五台县| 县级市| 淄博市| 阳高县| 浦县| 靖远县| 桐庐县| 嘉禾县| 奎屯市|