平常磨刀优化
一、不能被修改的状况,直接贴代码讲this
//建立一个实体类 public class Demo { private final int info = 123; public int getInfo() { return info; } } //反射修改的代码区域 public class TestFianl { public static void main(String[] args) { try { test(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void test() throws NoSuchFieldException, IllegalAccessException { Demo demo = new Demo(); System.out.println("反射修改以前 Demo 实例的值:"+demo.getInfo()); Field field = demo.getClass().getDeclaredField("info"); field.setAccessible(true);//灵魂语句 field.set(demo, 789); System.out.println("反射修改以后 Field 实例的值:"+field.get(demo)); System.out.println("反射修改以后 Demo 实例的值:"+demo.getInfo()); } } //输出结果为: 反射修改以前 Demo 实例的值:123 反射修改以后 Field 实例的值:789 反射修改以后 Demo 实例的值:123
一、注意这里的 修改的 成员变量 info 是被基本数据类型 int 修饰的code
二、编译的时候 被final修饰的成员变量会被优化,全部用到该变量的地方都被替换成了变量的内容 123get
第二句话解释看如下Demo 类反编译的代码io
public class Demo { private final int info = 123; public int getInfo() { return 123;//直接返回了 123 这个内容 而不是 info 这个变量 } }
二、能被修改的状况编译
//建立一个实体类 public class Demo { private final Integer info = 123; public Integer getInfo() { return info; } } //反射修改的代码区域 和 1 中的没有区别 public class TestFianl { public static void main(String[] args) { try { test(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void test() throws NoSuchFieldException, IllegalAccessException { Demo demo = new Demo(); System.out.println("反射修改以前 Demo 实例的值:"+demo.getInfo()); Field field = demo.getClass().getDeclaredField("info"); field.setAccessible(true);//灵魂语句 field.set(demo, 789); System.out.println("反射修改以后 Field 实例的值:"+field.get(demo)); System.out.println("反射修改以后 Demo 实例的值:"+demo.getInfo()); } } //输出结果为: 反射修改以前 Demo 实例的值:123 反射修改以后 Field 实例的值:789 反射修改以后 Demo 实例的值:789
一、注意这里的 修改的 成员变量 info 是被 包装类 Integer 修饰的class
二、定义的时候并无初始化值,getInfo方法返回的是info这个变量test
如下Demo 类反编译的代码变量
public class Demo { private final Integer info = Integer.valueOf(123);//定义的时候检查再初始化了值 public Integer getInfo() { return this.info; } }
因此成员变量在定义的时候没有初始化值的时候,就算用final修饰,同样能够被经过反射以后进行修改权限