Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制
Java的动态性支持学习一 - 反射机制 概念概述
Java的动态性支持学习二 - 反射机制 属性、方法、对象的操作
Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制
Java的动态性支持学习四 - 反射调用的性能对比
Java的动态性支持学习五 - 方法句柄 概念和句柄类型
Java的动态性支持学习六 - 方法句柄 获取和调用
Java的动态性支持学习七 - 方法句柄调用的性能对比
这篇博文学习下如何取消属性、方法、构造器的访问限制。
通过上节我们知道,当用Class对象的getDeclaredXXXs方法获得Field、Method或Constructor时由于访问限制的作用,可能有些字段、方法或构造器是不能访问的。如:
package net.oseye; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectTest { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{ Class c=User.class; Method mth=c.getDeclaredMethod("sayHello"); mth.invoke(c.newInstance(), new Object[0]); } } class User{ private void sayHello(){ System.out.println("我是私有方法"); } }
运行,或报异常:
Exception in thread "main" java.lang.IllegalAccessException: Class net.oseye.ReflectTest can not access a member of class net.oseye.User with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.oseye.ReflectTest.main(ReflectTest.java:11)
如果需要通过反射访问这些不允许访问的元素,则首先需要去除访问限制,然后在访问。去除访问限制,就需要使用到java.lang.reflect.AccessibleObject类,其中提供了一些用来去除访问限制的方法。Field、Method、Constructor类都是AccessibleObject类的子类。AccessibleObject类的常用方法:
- boolean isAccessible() 返回是否可以访问
- void setAccessible(boolean flag) 设置访问限制
- static void setAccessible(AccessibleObject[] array, boolean flag) 批量设置访问限制
Demo:
package net.oseye; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectTest { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{ Class c=User.class; Method mth=c.getDeclaredMethod("sayHello"); mth.setAccessible(true); mth.invoke(c.newInstance(), new Object[0]); } } class User{ private void sayHello(){ System.out.println("我是私有方法"); } }
输出:
我是私有方法
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。