Java 反射 调用私有域和方法(setAccessible)

@author ixenos

AccessibleObject类


Method、Field和Constructor类共同继承了AccessibleObject类,该基类有两个setAccessible方法能在运行时压制Java语言访问控制检查(Java language access control checks),从而能任意调用被私有化保护的方法、域和构造方法

public class AccessibleObjectextends Objectimplements AnnotatedElement

AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。

在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。 

两个setAccessible方法设置访问权限


static void setAccessible(AccessibleObject[] array, boolean flag)
          使用单一安全性检查(为了提高效率)为一组对象设置 accessible
标志的便捷方法。
 void setAccessible(boolean flag)

          将此对象的 accessible 标志设置为指示的布尔值。

setAccessible

public static void setAccessible(AccessibleObject[] array,
boolean flag)
throws SecurityException
使用单一安全性检查(为了提高效率)为一组对象设置 accessible 标志的便捷方法。

首先,如果存在安全管理器,则在 ReflectPermission("suppressAccessChecks") 权限下调用 checkPermission 方法。

如果 flagtrue,但是不能更改输入 array 的任何元素的可访问性(例如,如果元素对象是 Class 类的 Constructor 对象),则会引发 SecurityException。如果发生 SecurityException,对于少于(不包括)发生异常的元素的数组元素,可以将对象的可访问性设置为 flag;对于超出(包括)引发异常的元素的那些元素,则不更改其可访问性。

参数:
array - AccessibleObjects 的数组
flag - 每个对象中的 accessible 标志的新值
抛出:
SecurityException - 如果请求被拒绝。
另请参见:
SecurityManager.checkPermission(java.security.Permission), RuntimePermission

setAccessible

public void setAccessible(boolean flag)
throws SecurityException
将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。

首先,如果存在安全管理器,则在 ReflectPermission("suppressAccessChecks") 权限下调用 checkPermission 方法。

如果 flagtrue,并且不能更改此对象的可访问性(例如,如果此元素对象是 Class 类的 Constructor 对象),则会引发 SecurityException

如果此对象是 java.lang.Class 类的 Constructor 对象,并且 flag 为 true,则会引发 SecurityException

参数:
flag - accessible 标志的新值
抛出:
SecurityException - 如果请求被拒绝。
另请参见:
SecurityManager.checkPermission(java.security.Permission), RuntimePermission

示例


被测类:

 1 class Employee{
2 private int id;
3 private String name;
4 private int age;
5
6 public Employee(){
7
8 }
9 public Employee(int id, String name, int age){
10 this.id = id;
11 this.name = name;
12 this.age = age;
13 }
14
15 private void setId(int id){
16 this.id = id;
17 }
18 private int judge(int id){
19 return this.id - id;
20 }
21 private String sayHalo(String name){
22 return "Halo" + name;
23 }
24 }

Employee

测试类:

 public class PrivateTest{
public static void main(String[] args){
Employee em = new Employee(1, "Alex", 22);
//获取Class对象
Class<?> emClass = em.getClass(); //获取特定的声明了的方法
Method judgeMethod = emClass.getDeclaredMethod("judge", new Class[]{Integer.TYPE});
//setAccessible(boolean flag)使所有成员可以访问,访问之前设置
judgeMethod.setAccessible(true); //获取所有声明的方法
Method[] allMethods = emClass.getDeclaredMethods();
//AccessibleObject.setAccessible(AccessibleObject[] array,
boolean flag)批量给访问权限
AccessibleObject.setAccessible(allMethods, true); //下面就可以通过反射访问了
judgeMethod.invoke(em, new Object[]{3}); //or...
for(Method method : allMethods){
...
}
}
}

Java 反射 调用私有域和方法(setAccessible)的更多相关文章

  1. java反射调用某个对象的方法

    // 反射调用某个对象的方法 public Object invokeMethod(Object methodObject, String methodName, Object[] args) thr ...

  2. java反射调用私有方法和修改私有属性

    //调用私有方法package com.java.test; public class PrivateMethod { private String sayHello(String name) { r ...

  3. Java 反射 调用私有构造方法

    单例类: package singleton; public class SingletonTest { // 私有构造方法 private SingletonTest(){ System.out.p ...

  4. 利用java反射调用类的的私有方法--转

    原文:http://blog.csdn.net/woshinia/article/details/11766567 1,今天和一位朋友谈到父类私有方法的调用问题,本来以为利用反射很轻松就可以实现,因为 ...

  5. C# 反射调用私有事件

    原文:C# 反射调用私有事件 在 C# 反射调用私有事件经常会不知道如何写,本文告诉大家如何调用 假设有 A 类的代码定义了一个私有的事件 class A { private event EventH ...

  6. 2019-11-29-C#-反射调用私有事件

    原文:2019-11-29-C#-反射调用私有事件 title author date CreateTime categories C# 反射调用私有事件 lindexi 2019-11-29 08: ...

  7. Java反射理解(五)-- 方法反射的基本操作

    Java反射理解(五)-- 方法反射的基本操作 方法的反射 1. 如何获取某个方法 方法的名称和方法的参数列表才能唯一决定某个方法 2. 方法反射的操作 method.invoke(对象,参数列表) ...

  8. 2019-4-16-C#-使用反射获取私有属性的方法

    title author date CreateTime categories C# 使用反射获取私有属性的方法 lindexi 2019-4-16 10:13:3 +0800 2018-09-26 ...

  9. 2019-8-30-C#-反射调用私有事件

    title author date CreateTime categories C# 反射调用私有事件 lindexi 2019-08-30 08:52:57 +0800 2018-09-19 20: ...

随机推荐

  1. Smail语法

    1.数据类型 2.函数: Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type 注意参数与参数之间没有任何分隔符 3.函数调用: 4.关于s ...

  2. To the end

    身为一名初二狗的我也走过了半年.不管怎么说人生中也没有几个半年嘛.从九月到现在快四个月了,我也离中考越来越近了/郁闷/.但是还是要好好过唔.不过我想起这半学期还是挺充实的,至少没有浪费太多的时间.有些 ...

  3. CPU和GPU的区别

    个人认为CPU和GPU各有自己的适应领域.CPU(Central Processing Unit)计算核心较少,通常是双核.四核.八核,但是拥有大量的共享缓存.预测.乱序执行等优化,可以做逻辑非常复杂 ...

  4. iOS杂货

    iOS 导航栏TitleView居中的问题 titleVIew 默认情况下 是居中显示的,出现不居中的情况原因有两个:1,leftBarButtonItem,和rightBarButtonItem 留 ...

  5. 破译情报-NOIP2016提高组复赛模拟试题

    [题目描述] 最近国安人员截获了一份 RB 国的秘密情报, 全文都是经过加密的,每个单 词都很长.破译人员想到先把单词化简一下,方法是把每个单词尽量取短些的前 缀,但所取的前缀不能是其他单词的前缀. ...

  6. CodeForces 707D Persistent Bookcase

    $dfs$,优化. $return$操作说明该操作完成之后的状态和经过操作$k$之后的状态是一样的.因此我们可以建树,然后从根节点开始$dfs$一次(回溯的时候复原一下状态)就可以算出所有状态的答案. ...

  7. ZentaoPHP

    1.框架文档http://devel.cnezsoft.com/book/zentaophphelp/about-10.html zentaoPHP二次开发文档http://devel.cnezsof ...

  8. 给Cygwin重新安装curl

    之前已经安装过了cygwin了,但是重装了系统了. 不过发现cygwin倒是还可以继续使用. 现在想要使用其中的curl工具. 但是却在cygwin安装目录 E:\dev_install_root\c ...

  9. ES 6 : let与const

    1.let命令 [ 基本用法 ] let命令的用法与var类似,用于声明一个变量,但是let声明的变量只能在let所在的代码块内有效: 上述代码块中使用let和var声明了两个变量.然后在代码块之外调 ...

  10. php获取url字符串截取路径的文件名和扩展名

    <?php //获取连接里边的id $url = 'http://www.rong123.com/cjbkscbsd/x_dfsdfs/24454_1_1.html'; function get ...