zoukankan      html  css  js  c++  java
  • 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) + " "); //private :    10 System.out.printf("static : " + "%6s",Integer.toBinaryString(Modifier.STATIC) + " "); //static  :  1000 System.out.printf("Final : " + "%6s",Integer.toBinaryString(Modifier.FINAL) + " "); //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/

      

  • 相关阅读:
    Oracle 备份脚本
    Centos 安装DBI和ORACLE DBD
    人生到此初相见——北漂18年(10)
    备份上个月的日志
    mysql 授权
    竹杖芒鞋轻胜马,一蓑烟雨任平生——写在38岁生日
    haproxy 跨域访问:
    redis 配置说明
    vsftpd 500 OOPS: bad bool value in config file for: anon_world_readable_only
    vsftpd 配置虚拟用户
  • 原文地址:https://www.cnblogs.com/BlueStarWei/p/8955114.html
Copyright © 2011-2022 走看看