the journey is the reward...

          常用鏈接

          統(tǒng)計

          最新評論

          在運(yùn)行時,你能修改final field的值嗎?

           

          以[final int x=911] , [static final int x=912]為例,jdk1.6.0_16(為何如此版本詳細(xì),是因?yàn)橄旅孢€有個jdk的bug).

          樣例類:

          class Test { 
           private final  int x=911;//modifiers:final->18,non-final->2
           static final private  int y=912;//modifiers:final->26,non-final->10 
           public int getX(){
            return x;
           }  
           public static int getY(){
            return y;
           } 

           Java中的final field意指常量,賦值一次,不可改變.編譯器會對final field進(jìn)行如下的優(yōu)化:

          e.g:

          Test t=new Test();

          凡是在程序中對t.x的引用,編譯器都將以字面值911替換,getX()中的return x也會被替換成return 911;

          所以就算在運(yùn)行時你改變了x的值也無濟(jì)于事,編譯器對它們進(jìn)行的是靜態(tài)編譯.

          但是Test.class.getDeclaredField("x").getInt(t)除外;

           

          那么如何在運(yùn)行時改變final field x的值呢?

          private final  int x=911;Field.modifiers為18,而private int x=911;Field.modifiers為2.

          所以如果我們修改Field[Test.class.getDeclaredField("x")].modifiers由18[final]變?yōu)?[non-final],那么你就可以修改x的值了.

           Test tObj=new Test();  
           Field f_x=Test.class.getDeclaredField("x");  
            
            //修改modifiers 18->2
            Field f_f_x=f_x.getClass().getDeclaredField("modifiers");
            f_f_x.setAccessible(true);  
            f_f_x.setInt(f_x, 2/*non-final*/);
            
            f_x.setAccessible(true);
            f_x.setInt(tObj, 110);//改變x的值為110.  
            System.out.println("靜態(tài)編譯的x值:"+tObj.getX()+".------.運(yùn)行時改變了的值110:"+f_x.getInt(tObj));
             
            f_x.setInt(tObj, 111);//你可以繼續(xù)改變x的值為.  
            System.out.println(f_x.getInt(tObj));

          但是想恢復(fù)原來的modifiers,f_f_x.setInt(f_x, 18/*final*/);這是無效的,因?yàn)镕ield只會初始化它的FieldAccessor引用一次.

           

          在上面的過程中,我還發(fā)現(xiàn)了個jdk bug,你如果將上面的紅色代碼改為如下的代碼:

          f_f_x.setInt(f_x, 10/*這個數(shù)值是static non-final modifiers,而x是non-static的,這樣就會使f_x得到一個static FieldAccessor*/);那么會引發(fā)A fatal error has been detected by the Java Runtime Environment.并產(chǎn)生相應(yīng)的err log文件.顯然JVM沒有對這種情況加以處理.我已提交to sun bug report site. 

          sun 于2010-3-26通知我,他們已承認(rèn)該bug,bug id : 6938467.發(fā)布到外網(wǎng)可能有一到兩天的延遲.

          http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6938467 

           

           

           

          posted on 2010-03-18 09:36 adapterofcoms 閱讀(708) 評論(2)  編輯  收藏 所屬分類: java techs

          評論

          # re: 在運(yùn)行時,你能修改final field的值嗎? 2011-01-06 10:02 我們

          有的bug只是新功能的,其實(shí)不是bug  回復(fù)  更多評論   

          # re: 在運(yùn)行時,你能修改final field的值嗎? 2011-01-06 10:03 我們

          真正的bug是自身矛盾  回復(fù)  更多評論   

          主站蜘蛛池模板: 沙田区| 渭源县| 依兰县| 乌兰县| 望都县| 诸暨市| 博客| 许昌县| 碌曲县| 婺源县| 广元市| 思南县| 高清| 彭泽县| 五台县| 铁岭县| 衢州市| 乳山市| 镇江市| 汪清县| 江都市| 涟水县| 泰州市| 万山特区| 会东县| 兖州市| 余江县| 斗六市| 西充县| 饶阳县| 南投县| 栾川县| 房山区| 福清市| 松潘县| 五峰| 大兴区| 余姚市| 淳安县| 汤阴县| 孝昌县|