java反射 setAccess,Java反射 - setAccessible的影响(真)Java反射 - setAccessib

我使用了一些注释动态设置在类字段的值。 因为我想做到这一点,无论它是公共的,保护的,还是私人的,我是一个呼叫setAccessible(true)每次Field对象上调用之前set()方法。 我的问题是什么样的影响呢的setAccessible()调用已经在球场上本身?

更具体地讲,说这是一个私人领域,这组代码调用setAccessible(true) 。 如果代码中的其他地方是那么地检索通过反射同场,将现场已经可以访问? 抑或是getDeclaredFields()和getDeclaredField()方法每次返回Field对象的新实例?

我想提出这个问题的另一种方式是,如果我叫setAccessible(true) ,是多么重要的是它设置回原始值,我做了之后?

Answer 1:

随着setAccessible()更改的行为AccessibleObject ,即Field实例,而不是类的实际领域。 这里的文档 (节选):

的值true表明,当它被使用的反射对象应该抑制为Java语言访问控制检查

和一个可运行的例子:

public class FieldAccessible {

public static class MyClass {

private String theField;

}

public static void main(String[] args) throws Exception {

MyClass myClass = new MyClass();

Field field1 = myClass.getClass().getDeclaredField("theField");

field1.setAccessible(true);

System.out.println(field1.get(myClass)); // no exception

Field field2 = myClass.getClass().getDeclaredField("theField");

System.out.println(field2.get(myClass)); // IllegalAccessException

}

}

Answer 2:

该getDeclaredField方法每次都返回一个新的对象,正是因为这个对象具有可变的accessible标志。 所以,没有必要重新设置标志。 你可以找到的全部细节这个博客帖子 。

Answer 3:

正如其他海报指出, setAccessible只适用于你的那个实例java.lang.reflect.Field ,所以设置无障碍设施恢复到原来的状态是没有必要的。

然而...

如果您想您的通话field.setAccessible(true)是持久性的,你需要使用下面的方法java.lang.Class和java.lang.reflect.Field 。 面向公众的方式发送给您的副本 Field实例,因此它“忘记”以后每次做类似class.getField(name)

import java.lang.reflect.*;

import sun.reflect.FieldAccessor;

public class Reflect {

private static Method privateGetDeclaredFields;

private static Method getFieldAccessor;

public static Field[] fields(Class> clazz) throws Exception {

return (Field[]) privateGetDeclaredFields.invoke(clazz, false);

}

public static T get(Object instance, Field field) throws Exception {

return ((FieldAccessor) getFieldAccessor.invoke(field, instance)).get(instance);

}

public static void set(Object instance, Field field, Object value) throws Exception {

((FieldAccessor) getFieldAccessor.invoke(field, instance)).set(instance, value);

}

static {

try {

// These are used to access the direct Field instances instead of the copies you normally get through #getDeclaredFields.

privateGetDeclaredFields = Class.class.getDeclaredMethod("privateGetDeclaredFields", boolean.class);

privateGetDeclaredFields.setAccessible(true);

getFieldAccessor = Field.class.getDeclaredMethod("getFieldAccessor", Object.class);

getFieldAccessor.setAccessible(true);

} catch (Exception e) {

// Should only occur if the internals change.

e.printStackTrace();

}

}

}

Answer 4:

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class PrivateVariableAcc {

public static void main(String[] args) throws Exception {

PrivateVarTest myClass = new PrivateVarTest();

Field field1 = myClass.getClass().getDeclaredField("a");

field1.setAccessible(true);

System.out.println("This is access the private field-"

+ field1.get(myClass));

Method mm = myClass.getClass().getDeclaredMethod("getA");

mm.setAccessible(true);

System.out.println("This is calling the private method-"

+ mm.invoke(myClass, null));

}

}

文章来源: Java reflection - impact of setAccessible(true)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值