Java反射之修改常量值


1. 通過反射修改常量的值

package com.blueStarWei.invoke;

import java.lang.reflect.Field;

public class ModifyFinalField {
    
    private final Integer KEY_EXIT = 1024;
    
    private static void invoke() throws Exception{
        ModifyFinalField mff = new ModifyFinalField();
        
        System.out.println("Before modifying : "+mff.KEY_EXIT);//1024         
//獲取屬性【private final java.lang.Integer com.blueStarWei.invoke.ModifyFinalField.KEY_EXIT】 Field field
= mff.getClass().getDeclaredField("KEY_EXIT");
//忽略屬性的訪問權限 field.setAccessible(
true);
//設置新的值 field.set(mff,
512); System.out.println("After modifying : "+mff.KEY_EXIT);//512 } public static void main(String[] args) { try { invoke(); } catch (Exception e) { e.printStackTrace(); } } }

 

2.通過反射修改靜態常量的值

package com.blueStarWei.invoke;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ModifyFinalField {
    
    private static final Integer KEY_EXIT = 1024;
    
    private static void invoke() throws Exception{
        System.out.println("Before modifying : "+ModifyFinalField.KEY_EXIT);//1024         
//獲取屬性【private final java.lang.Integer com.blueStarWei.invoke.ModifyFinalField.KEY_EXIT】 Field field
= ModifyFinalField.class.getDeclaredField("KEY_EXIT"); //忽略final修飾符【注釋一】 Field modifiers = Field.class.getDeclaredField("modifiers"); modifiers.setAccessible(true); modifiers.setInt(field, field.getModifiers()&~Modifier.FINAL);
//設置新的值 field.set(
null, 512); System.out.println("After modifying : "+ModifyFinalField.KEY_EXIT);//512 } public static void main(String[] args) { try { invoke(); } catch (Exception e) { e.printStackTrace(); } } }

     2.1 注釋一

public class FinalDemo {

    private static final Integer KEY = 12;
    
    public static void main(String[] args) throws NoSuchFieldException, SecurityException {
        Field field = FinalDemo.class.getDeclaredField("KEY");
//getModifiers()以整數形式返回由此 Field 對象表示的字段的 Java 語言修飾符。
System.out.println("private static final : "+Integer.toBinaryString(field.getModifiers())); //private static final : 11010
 System.out.println("---------------分割線-------------------");
System.out.printf(
"private : " + "%6s",Integer.toBinaryString(Modifier.PRIVATE) + "\n"); //private :    10 System.out.printf("static : " + "%6s",Integer.toBinaryString(Modifier.STATIC) + "\n"); //static  :  1000 System.out.printf("Final : " + "%6s",Integer.toBinaryString(Modifier.FINAL) + "\n"); //Final   : 10000 } }

 

3.注意事項

    3.1 基本數據類型和String類型的final常量在編譯時,編譯器會自動將用到該常量的地方用實際值替換(不管是否是靜態的);而封裝類型不存在該現象。

static final int A = 23;
if(i > A){
  System.out.println(A);
}

//自動編譯成

static final int A = 23;
if(i > 23){
  System.out.println(23);
}

    3.2 導致的問題:即使通過反射修改了基本數據類型和String類型的final常量的值,但是使用該常量時,值仍然是原來的值。

package com.blueStarWei.invoke;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class SpecialCase {

    private static final int NUM = 1024;
    
    private static void invok1() throws Exception {
        System.out.println("Before modify : "+SpecialCase.NUM);//Before modify : 1024
        Field field = SpecialCase.class.getDeclaredField("NUM");
        field.setAccessible(true);
        Field modifiers = Field.class.getDeclaredField("modifiers");
        modifiers.setAccessible(true);
        modifiers.setInt(field, field.getModifiers()&~Modifier.FINAL);
        field.set(null, 512);
        //在下一行打斷點,會發現NUM的值已經變為512,但是輸出的仍然是1024
        System.out.println("After modify : "+SpecialCase.NUM);//After modify : 1024
    }
    
    public static void main(String[] args) {
        try {
            invok1();
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
}

 

    更多內容,請訪問:http://www.cnblogs.com/BlueStarWei/

  


免責聲明!

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



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