篡改Java final参数

       在Java语法里, final关键字用在声明参数时, 该参数叫做常量; 否则叫做变量。 

       final关键字的作用是值(或引用)不可改, 但引用的对象可以改值。

常量的一般声明方式:

    class SomeClass {
        final int SOME_CONSTANT1 = 1;
        final int SOME_CONSTANT2 = 2;
        
        ......
    }
        声明时为final参数赋初值, 这种情况下不能篡改。
      但是声明final参数时不赋初值, 这种情况下是可以篡改的!!! 例如:  final int a; a = 1;   可以通过反射修改参数a的值。

      为什么使用关键字后参数就是常量, 不能修改了呢???

  其实final属性以及访问权限都对应一个二进制比特位, 在java.lang.reflect.Modifier.java里声明:

public class Modifier {
 /**
     * The {@code int} value representing the {@code private}
     * modifier.
     */
    public static final int PRIVATE          = 0x00000002;

    /**
     * The {@code int} value representing the {@code protected}
     * modifier.
     */
    public static final int PROTECTED        = 0x00000004;

    /**
     * The {@code int} value representing the {@code static}
     * modifier.
     */
    public static final int STATIC           = 0x00000008;

    /**
     * The {@code int} value representing the {@code final}
     * modifier.
     */
    public static final int FINAL            = 0x00000010;

.......
}
        那么是否可以篡改函数、属性的访问特性呢? 答案是肯定的。 下面以修改final属性为例:


  static class Test {
        private final int a;  //赋值后仍然可以该
        private int b;
        private final int c = 3;    //改不了

        Test(int param1, int param2) {
            a = param1;
            b = param2;
        }

        public int getValueA() {
            return a;
        }

        public int getValueB() {
            return b;
        }

        public int getValueC() { return c; }
    }

    /**
     * 清除final属性, 及修改modifier参数
     * @param field
     */
    public static void removeFieldFinalModifier(final Field field) {
        if (field == null) {
            return;
        }

        try {
            if (Modifier.isFinal(field.getModifiers())) {
                final Field modifiersField = Field.class.getDeclaredField("modifiers");
                final boolean doForceAccess = !modifiersField.isAccessible();
                if (doForceAccess) {
                    modifiersField.setAccessible(true);
                }
                try {
                    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
                } finally {
                    if (doForceAccess) {
                        modifiersField.setAccessible(false);
                    }
                }
            }
        } catch (final NoSuchFieldException ignored) {
            // The field class contains always a modifiers field
        } catch (final IllegalAccessException ignored) {
            // The modifiers field is made accessible
        }
    }

    public static void main(String[] args) {
        Test obj = new Test(1, 2);   //a等于1, b等于2
        Class clz = Test.class;

        System.out.println("final属性a篡改前:" + obj.getValueA());
        System.out.println("非final属性b篡改前:" + obj.getValueB());
        System.out.println("final属性c篡改前:" + obj.getValueC());
        try {
            Field fieldA = clz.getDeclaredField("a");
            fieldA.setAccessible(true);
            Field fieldB = clz.getDeclaredField("b");
            fieldB.setAccessible(true);
            Field fieldC = clz.getDeclaredField("c");
            fieldC.setAccessible(true);

            removeFieldFinalModifier(fieldA);   //删除final限制
            fieldA.setInt(obj, 11);  //final属性a的值从1变为11

            fieldB.setInt(obj, 22);    //值变为22

            removeFieldFinalModifier(fieldC);   //删除final限制
            fieldC.setInt(obj, 33);      //无法篡改

            System.out.println("---------------以下是结果----------------");
            System.out.println("final属性a篡改后:" + obj.getValueA());
            System.out.println("非final属性b篡改后:" + obj.getValueB());
            System.out.println("final属性c篡改后:" + obj.getValueC());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

输出日志:

final属性a篡改前:1
非final属性b篡改前:2
final属性c篡改前:3
---------------以下是结果----------------
final属性a篡改后:11
非final属性b篡改后:22
final属性c篡改后:3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值