黑马程序员技术交流社区

标题: 关于用final修饰符修饰成员变量在反射中的一些问题 [打印本页]

作者: vmvm555    时间: 2013-1-21 16:01
标题: 关于用final修饰符修饰成员变量在反射中的一些问题
本帖最后由 vmvm555 于 2013-1-23 19:10 编辑

众所周知,用private修饰的成员变量无法直接访问,但可以通过反射强制突破,拿到成员变量甚至修改它,但是如果该成员变量用final修饰符修饰,反射应该无法修改它吧,我的问题在下面一段代码
  1. import java.lang.reflect.Field;


  2. public class TestArrayReflect {

  3.         public static void main(String[] args) throws Exception {
  4.                 final Dog dog1 = new Dog(5, "red");
  5.                 Field field = dog1.getClass().getDeclaredField("age");
  6.                 field.setAccessible(true);
  7.                 System.out.println(field.get(dog1));
  8.                 field.setInt(dog1, 7);
  9.                 System.out.println(field.get(dog1));
  10.                 Field field2 = dog1.getClass().getDeclaredField("WEIGHT");
  11.                 field2.setAccessible(true);
  12.                 System.out.println(field2.get(null));
  13.                 field2.setInt(null, 25);
  14.                 System.out.println(field2.get(null));
  15.         }
  16. }
  17. class Dog {
  18.         private static final int WEIGHT = 20;
  19.         private final int age;
  20.         private String color;
  21.         
  22.         public Dog(int age, String color) {
  23.                 super();
  24.                 this.age = age;
  25.                 this.color = color;
  26.         }
  27.         public int getAge() {
  28.                 return age;
  29.         }
  30. /*        public void setAge(int age) {
  31.                 this.age = age;
  32.         }*/
  33.         public String getColor() {
  34.                 return color;
  35.         }
  36.         public void setColor(String color) {
  37.                 this.color = color;
  38.         }
  39.         
  40. }
复制代码
为什么用final修饰的成员变量能够更改它的值(final不代表该变量无法更改吗),就算能更改,为什么用 static final修饰的常量又不允许修改抛出了
  1. Exception in thread "main" java.lang.IllegalAccessException: Can not set static final int field Dog.WEIGHT to (int)25
  2.         at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:55)
  3.         at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:79)
  4.         at sun.reflect.UnsafeQualifiedStaticIntegerFieldAccessorImpl.setInt(UnsafeQualifiedStaticIntegerFieldAccessorImpl.java:111)
  5.         at java.lang.reflect.Field.setInt(Field.java:802)
  6.         at TestArrayReflect.main(TestArrayReflect.java:16)
复制代码
那位大侠来解释一下啊,谢谢

作者: 惠晖    时间: 2013-1-23 11:28
我猜的哈,  用反射 可以躲避编译器报错,     而加了static 就是正真的运行时的异常了。。
作者: 黄锦成    时间: 2013-1-23 11:52
final应该只能在编译时期有用吧,就像泛型那样,可以通过反射插入其他类型的元素

static final 则是常量,已经被固定了
作者: vmvm555    时间: 2013-1-23 19:07
黄锦成 发表于 2013-1-23 11:52
final应该只能在编译时期有用吧,就像泛型那样,可以通过反射插入其他类型的元素

static final 则是常量, ...

楼上的的,谢谢了,稍微有一点明白了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2