java反射
在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为java的反射机制。
Java 反射是 Java 被视为动态语言的一个关键性质。这个机制允许程序在运行时透过 Reflection APIs 取得任何一个已知名称的 class 的内部信息,包括其modifiers(诸如 public, static 等)、superclass(例如 Object)、实现之interfaces(例如 Cloneable),也包括 fields 和 methods 的所有信息,并可于运行时改变 fields 内容或唤起 methods。
反射核心Class.java
每一个类都有一个Class对象,每当编译一个新类就产生一个Class对象,基本类型 (boolean, byte, char, short, int, long, float, and double)有Class对象,数组有Class对象,就连关键字void也有Class对象(void.class)。Class对象对应着java.lang.Class类,如果说类是对象抽象和集合的话,那么Class类就是对类的抽象和集合。
Class类没有公共的构造方法,Class对象是在类加载的时候由Java虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。一个类被加载到内存并供我们使用需要经历如下三个阶段:
加载,这是由类加载器(ClassLoader)执行的。通过一个类的全限定名来获取其定义的二进制字节流(Class字节码),将这个字节流所代表的静态存储结构转化为方法去的运行时数据接口,根据字节码在java堆中生成一个代表这个类的java.lang.Class对象。
链接。在链接阶段将验证Class文件中的字节流包含的信息是否符合当前虚拟机的要求,为静态域分配存储空间并设置类变量的初始值(默认的零值),并且如果必需的话,将常量池中的符号引用转化为直接引用。
初始化。到了此阶段,才真正开始执行类中定义的java程序代码。用于执行该类的静态初始器和静态初始块,如果该类有父类的话,则优先对其父类进行初始化。
所有的类都是在对其第一次使用时,动态加载到JVM中的(懒加载)。当程序创建第一个对类的静态成员的引用时,就会加载这个类。使用new创建类对象的时候也会被当作对类的静态成员的引用。因此java程序程序在它开始运行之前并非被完全加载,其各个类都是在必需时才加载的。这一点与许多传统语言都不同。动态加载使能的行为,在诸如C++这样的静态加载语言中是很难或者根本不可能复制的。
对于任意一个Class对象,都需要由它的类加载器和这个类本身一同确定其在就Java虚拟机中的唯一性,也就是说,即使两个Class对象来源于同一个Class文件,只要加载它们的类加载器不同,那这两个Class对象就必定不相等。这里的“相等”包括了代表类的Class对象的equals()、isAssignableFrom()、isInstance()等方法的返回结果,也包括了使用instanceof关键字对对象所属关系的判定结果。所以在java虚拟机中使用双亲委派模型来组织类加载器之间的关系,来保证Class对象的唯一性。
反射方式
在类加载阶段,类加载器首先检查这个类的Class对象是否已经被加载。如果尚未加载,默认的类加载器就会根据类的全限定名查找.class文件。在这个类的字节码被加载时,它们会接受验证,以确保其没有被破坏,并且不包含不良java代码。一旦某个类的Class对象被载入内存,我们就可以它来创建这个类的所有对象。
有三种获得Class对象的方式:
- 调 用getClass()
- 运行 .class语法
- 运行Class.forName()
ReflectionData
为了提高反射的性能,缓存显然是必须的。class类内部有一个useCaches静态变量来标记是否使用缓存,这个值可以通过外部配置项sun.reflect.noCaches进行开关。class类内部提供了一个ReflectionData内部类用来存放反射数据的缓存,并声明了一个reflectionData域,由于稍后进行按需延迟加载并缓存,所以这个域并没有指向一个实例化的ReflectionData对象。
newInstance()实例化并分配内存空间,但是前提要求 这个类已经加载。
getSuperclass()返回当前实体类的父类。
setAccessible(true)开启访问权限的
java字段反射
Fields类
public Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段
public Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段
public Field getDeclared Field(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段
public Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
getFields 和 getDeclaredFields 区别:
getFields 返回的是申明为 public 的属性,包括父类中定义,
getDeclaredFields 返回的是指定类定义的所有定义的属性,不包括父类的
java方法反射
public Method getMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
public Method[] getMethods()
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
public MethodgetDeclaredMethod(Stringname,Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法
public Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
java构造函数反射
通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例
Class 类提供了几个方法获取类的构造器。
public Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
public Constructor<?>[] getConstructors()
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或
接口的指定构造方法
public Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。它们是公共、保护、默认(包)访问和私有构造方法
java反射对象创建
- 调用类的 Class 对象的 newInstance 方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败
Class<?> classType = ExtendType.class;
Object inst = classType.newInstance();
- 调用默认 Constructor 对象的 newInstance 方法
Class<?> classType = ExtendType.class;
Constructor<?>constructor=classType.getConstructor();
Object inst = constructor1.newInstance();
- 调用带参数 Constructor 对象的 newInstance 方法
Constructor<?> constructor2 =classType.getDeclaredConstructor(int.class, String.class);
Object inst = constructor2.newInstance(1, "123");
代理
代理核心
代理生成核心方法:Proxy->public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
动态代理核心反射代码:InvocationHandler->public Object invoke(Object proxy, Method method, Object[] args)->Method.invoke(this.object, args)
静态代理
静态代理其实就是程序运行之前,提前写好被代理类的代理类,编译之后直接运行即可起到代理的效果,下面会用简单的例子来说明。在例子中,首先我们有一个顶级接口(ProductFactory),这个接口需要代理类(ProxyTeaProduct)和被代理类(TeaProduct)都去实现它,在被代理类中我们重写需要实现的方法(action),该方法会交由代理类去选择是否执行和在何处执行;被代理类中主要是提供顶级接口的的一个引用但是引用实际指向的对象则是实现了该接口的代理类(使用多态的特点,在代理类中提供构造器传递实际的对象引用)。分析之后,我们通过下面这个图理解一下这个过程。
package com.somin.test.代理模式;
interface Person1
{
void earnMoney();
}
class Worker1 implements Person1
{
private String name;
public Worker1(String name) {
this.name = name;
}
public void earnMoney()
{
System.out.println(name+":打工人,打工魂");
}
}
class WorkerProxy implements Person1
{
Worker1 worker;
public WorkerProxy(Worker1 worker){
this.worker=worker;
}
public void earnMoney()
{
worker.earnMoney();
}
}
public class 静态工厂测试
{
public static void main(String[] args)
{
Worker1 worker=new Worker1("小明");
WorkerProxy proxy=new WorkerProxy(worker);
proxy.earnMoney();
}
}
动态代理
动态代理是指通过代理类来调用它对象的方法,并且是在程序运行使其根据需要创建目标类型的代理对象。它只提供一个代理类,我们只需要在运行时候动态传递给需要他代理的对象就可以完成对不同接口的服务了。
package com.somin.test.代理模式;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Person2
{
void earnMoney();
}
class Worker2 implements Person2
{
private String name;
public Worker2(String name) {
this.name = name;
}
public void earnMoney()
{
System.out.println(name+":打工人,打工魂");
}
}
class WorkerInvocationHandler<T> implements InvocationHandler
{
T worker;
public WorkerInvocationHandler(T worker){
this.worker=worker;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("代理执行" +method.getName() + "方法");
return method.invoke(worker, args);
}
}
public class 动态工厂测试
{
public static void main(String[] args)
{
Worker worker=new Worker("小明");
WorkerInvocationHandler handler=new WorkerInvocationHandler(worker);
Person2 proxy= (Person2)Proxy.newProxyInstance(Person2.class.getClassLoader(),new Class<?>[]{Person2.class},handler);
proxy.earnMoney();
}
}
AOP简单实现
AOP(Aspect Orient Programming)我们一般称之为面向切面编程,作为一种面向对象的补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志记录等。AOP实现的关键在于AOP的代理(实际实现上有静态代理和动态代理),我们下面使用JDK的动态代理的方式模拟实现下面的场景。
package com.somin.test.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//基于jdk的针对接口实现动态代理,要求的接口
interface Target {
void login();
void logout();
}
//被代理类
class TargetImpl implements Target {
public void login() {
System.out.println("login......");
}
public void logout() {
System.out.println("logout......");
}
}
class Util {
public void printLog() {
System.out.println("我是记录打印日志功能的方法......");
}
public void getProperties() {
System.out.println("我是获取配置文件信息功能的方法......");
}
}
//实现了InvocationHandler的统一代理类
class DynamicProxyHandler implements InvocationHandler {
private Object object;
/**
* 参数为obj,是应对对不同的被代理类,都能绑定与该代理类的代理关系
* 这个方法会将targetOne指向实际实现接口的子类对象,即当前代理类实际要去代理的那个类
*/
public void setObj(Object obj) {
this.object = obj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Util util = new Util();
util.getProperties();
Object object = method.invoke(this.object, args); //这个方法是个动态的方法,可以是login,可以是logout,具体在测试调用中调用不同方法
util.printLog();
return object;
}
}
//该类的主要作用就是动态的创建一个代理类的对象,同时需要执行被代理类
class MyDynamicProxyUtil {
//参数obj表示动态的传递进来被代理类的对象
public static Object getProxyInstance(Object object) {
//获取代理类对象
DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler();
dynamicProxyHandler.setObj(object);
//设置好代理类与被代理类之间的关系后,返回一个代理类的对象
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), dynamicProxyHandler);
}
}
public class TestAop
{
public static void main(String[] args) {
//获得被代理类
Target target = new TargetImpl();
//通过代理类工具类,设置实际与代理类绑定的被代理类,并返回一个代理类对象执行实际的方法
Target execute = (Target) MyDynamicProxyUtil.getProxyInstance(target);
execute.login();
execute.logout();
}
}
使用反射的缺点
性能
反射包括了一些动态类型,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。
安全限制
使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行。
内部暴露
由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
Class源码注释
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {
private static final int ANNOTATION= 0x00002000; //注释类型
private static final int ENUM = 0x00004000;//枚举类型
private static final int SYNTHETIC = 0x00001000;//合成类型
//注册本地方法
private static native void registerNatives();
static {
registerNatives();
}
//私有方法 给jvm创造创造类的时候使用的
private Class(ClassLoader loader) {
// Initialize final field for classLoader. The initialization value of non-null
// prevents future JIT optimizations from assuming this final field is null.
classLoader = loader;
}
// 重写Object的toString
public String toString() {
//区别了接口和普通类的
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}
//toString的详细版
public String toGenericString() {
if (isPrimitive()) {
return toString();
} else {
StringBuilder sb = new StringBuilder();
// Class modifiers are a superset of interface modifiers
int modifiers = getModifiers() & Modifier.classModifiers();
if (modifiers != 0) {
sb.append(Modifier.toString(modifiers));
sb.append(' ');
}
if (isAnnotation()) {
sb.append('@');
}
if (isInterface()) { // Note: all annotation types are interfaces
sb.append("interface");
} else {
if (isEnum())
sb.append("enum");
else
sb.append("class");
}
sb.append(' ');
sb.append(getName());
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append('<');
for(TypeVariable<?> typeparm: typeparms) {
if (!first)
sb.append(',');
sb.append(typeparm.getTypeName());
first = false;
}
sb.append('>');
}
return sb.toString();
}
}
//通过类全限定名获得该类的类对象
@CallerSensitive //用来找到真正发起反射请求的类
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
//方法返回与给定字符串名的类或接口的Class对象,使用给定的类加载器。使用指定的加载器加载
@CallerSensitive
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
{
Class<?> caller = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Reflective call to get caller class is only needed if a security manager
// is present. Avoid the overhead of making this call otherwise.
caller = Reflection.getCallerClass();
if (sun.misc.VM.isSystemDomainLoader(loader)) {
ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
return forName0(name, initialize, loader, caller);
}
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader,
Class<?> caller)
throws ClassNotFoundException;
//通过newInstance 生成一个类的实例 默认调用无参构造方法
@CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw (InstantiationException)
new InstantiationException(getName()).initCause(e);
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
//缓存已经调用的共有方法
private volatile transient Constructor<T> cachedConstructor;
//缓存class 对象
private volatile transient Class<?> newInstanceCallerCache;
//判断一个对象是否该class的实例
public native boolean isInstance(Object obj);
//判断一个该类和另一个类cls是否相同或是另一个类的超类或接口
public native boolean isAssignableFrom(Class<?> cls);
//判断一个对象实例是否是一个 类/接口的/其子类子接口 的实例
public native boolean isInterface();
//判断是否出租
public native boolean isArray();
//判断该Class是否是基本类型+特殊类型,
/**
* @see java.lang.Boolean#TYPE
* @see java.lang.Character#TYPE
* @see java.lang.Byte#TYPE
* @see java.lang.Short#TYPE
* @see java.lang.Integer#TYPE
* @see java.lang.Long#TYPE
* @see java.lang.Float#TYPE
* @see java.lang.Double#TYPE
* @see java.lang.Void#TYPE 特殊类型
*/
public native boolean isPrimitive();
//判断该Class是否是注释类型
public boolean isAnnotation() {
return (getModifiers() & ANNOTATION) != 0;
}
//判断是否合成类型( 是由编译器引入的字段、方法、类或其他结构)
public boolean isSynthetic() {
return (getModifiers() & SYNTHETIC) != 0;
}
// 获取类名
public String getName() {
String name = this.name;
if (name == null)
this.name = name = getName0();
return name;
}
// cache the name to reduce the number of calls into the VM
private transient String name;
private native String getName0();
//返回类加载器
@CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
// Package-private to allow ClassLoader access
ClassLoader getClassLoader0() { return classLoader; }
// Initialized in JVM not by private constructor
// This field is filtered from reflection access, i.e. getDeclaredField
// will throw NoSuchFieldException
private final ClassLoader classLoader;
//返回该类中变量字段的类型变量数组
@SuppressWarnings("unchecked")
public TypeVariable<Class<T>>[] getTypeParameters() {
ClassRepository info = getGenericInfo();
if (info != null)
return (TypeVariable<Class<T>>[])info.getTypeParameters();
else
return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
}
//获得该类的直接父类的Class对象,如果该类是接口,则返回null
public native Class<? super T> getSuperclass();
//返回详细版的父类class对象
public Type getGenericSuperclass() {
ClassRepository info = getGenericInfo();
if (info == null) {
return getSuperclass();
}
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
if (isInterface()) {
return null;
}
return info.getSuperclass();
}
//获取类的包路径
public Package getPackage() {
return Package.getPackage(this);
}
//获取该类直接实现的所有接口的数组
public Class<?>[] getInterfaces() {
ReflectionData<T> rd = reflectionData();
if (rd == null) {
// no cloning required
return getInterfaces0();
} else {
Class<?>[] interfaces = rd.interfaces;
if (interfaces == null) {
interfaces = getInterfaces0();
rd.interfaces = interfaces;
}
// defensively copy before handing over to user code
return interfaces.clone();
}
}
private native Class<?>[] getInterfaces0();
//获取所有接口,同上面的不同之处在于,若超接口是参数化类型(泛型)则返回的是其实际类型
public Type[] getGenericInterfaces() {
ClassRepository info = getGenericInfo();
return (info == null) ? getInterfaces() : info.getSuperInterfaces();
}
//返回数组类型,若该类不是数组,返回null
public native Class<?> getComponentType();
//返回修饰符对应的int值
public native int getModifiers();
/**
* Gets the signers of this class.
*
* @return the signers of this class, or null if there are no signers. In
* particular, this method returns null if this object represents
* a primitive type or void.
* @since JDK1.1
*/
public native Object[] getSigners();
/**
* Set the signers of this class.
*/
native void setSigners(Object[] signers);
//如果这个类是本地或匿名类,返回的底层类的立即封闭方法,否则返回null。
@CallerSensitive
public Method getEnclosingMethod() throws SecurityException {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
if (enclosingInfo == null)
return null;
else {
if (!enclosingInfo.isMethod())
return null;
MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Class<?> returnType = toClass(typeInfo.getReturnType());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// Convert Types to Classes; returned types *should*
// be class objects since the methodDescriptor's used
// don't have generics information
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
// Perform access check
Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
/*
* Loop over all declared methods; match method name,
* number of and type of parameters, *and* return
* type. Matching return type is also necessary
* because of covariant returns, etc.
*/
for(Method m: enclosingCandidate.getDeclaredMethods()) {
if (m.getName().equals(enclosingInfo.getName()) ) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches) { // finally, check return type
if (m.getReturnType().equals(returnType) )
return m;
}
}
}
}
throw new InternalError("Enclosing method not found");
}
}
private native Object[] getEnclosingMethod0();
private EnclosingMethodInfo getEnclosingMethodInfo() {
Object[] enclosingInfo = getEnclosingMethod0();
if (enclosingInfo == null)
return null;
else {
return new EnclosingMethodInfo(enclosingInfo);
}
}
private final static class EnclosingMethodInfo {
private Class<?> enclosingClass;
private String name;
private String descriptor;
private EnclosingMethodInfo(Object[] enclosingInfo) {
if (enclosingInfo.length != 3)
throw new InternalError("Malformed enclosing method information");
try {
// The array is expected to have three elements:
// the immediately enclosing class
enclosingClass = (Class<?>) enclosingInfo[0];
assert(enclosingClass != null);
// the immediately enclosing method or constructor's
// name (can be null).
name = (String) enclosingInfo[1];
// the immediately enclosing method or constructor's
// descriptor (null iff name is).
descriptor = (String) enclosingInfo[2];
assert((name != null && descriptor != null) || name == descriptor);
} catch (ClassCastException cce) {
throw new InternalError("Invalid type in enclosing method information", cce);
}
}
boolean isPartial() {
return enclosingClass == null || name == null || descriptor == null;
}
boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
Class<?> getEnclosingClass() { return enclosingClass; }
String getName() { return name; }
String getDescriptor() { return descriptor; }
}
private static Class<?> toClass(Type o) {
if (o instanceof GenericArrayType)
return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
0)
.getClass();
return (Class<?>)o;
}
//如果这个类是本地或匿名类,返回的底层类的立即封闭构造方法,否则返回null。
@CallerS @CallerSensitive
public Constructor<?> getEnclosingConstructor() throws SecurityException {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
if (enclosingInfo == null)
return null;
else {
if (!enclosingInfo.isConstructor())
return null;
ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// Convert Types to Classes; returned types *should*
// be class objects since the methodDescriptor's used
// don't have generics information
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
// Perform access check
Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
/*
* Loop over all declared constructors; match number
* of and type of parameters.
*/
for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches)
return c;
}
}
throw new InternalError("Enclosing constructor not found");
}
}
//返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
@CallerSensitive
public Class<?> getDeclaringClass() throws SecurityException {
final Class<?> candidate = getDeclaringClass0();
if (candidate != null)
candidate.checkPackageAccess(
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
return candidate;
}
private native Class<?> getDeclaringClass0();
//如果这个类是本地或匿名类,返回底层类的立即封闭类。
@CallerSensitive
public Class<?> getEnclosingClass() throws SecurityException {
// There are five kinds of classes (or interfaces):
// a) Top level classes
// b) Nested classes (static member classes)
// c) Inner classes (non-static member classes)
// d) Local classes (named classes declared within a method)
// e) Anonymous classes
// JVM Spec 4.8.6: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
Class<?> enclosingCandidate;
if (enclosingInfo == null) {
// This is a top level or a nested class or an inner class (a, b, or c)
enclosingCandidate = getDeclaringClass();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// This is a local class or an anonymous class (d or e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("Malformed enclosing method information");
else
enclosingCandidate = enclosingClass;
}
if (enclosingCandidate != null)
enclosingCandidate.checkPackageAccess(
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
return enclosingCandidate;
}
//获取源代码中给出的“底层类”简称,木有包名,如果是个匿名函数则返回空空字符串。注意和getName区分
public String getSimpleName() {
if (isArray())
return getComponentType().getSimpleName()+"[]";
String simpleName = getSimpleBinaryName();
if (simpleName == null) { // top level class
simpleName = getName();
return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
}
// According to JLS3 "Binary Compatibility" (13.1) the binary
// name of non-package classes (not top level) is the binary
// name of the immediately enclosing class followed by a '$' followed by:
// (for nested and inner classes): the simple name.
// (for local classes): 1 or more digits followed by the simple name.
// (for anonymous classes): 1 or more digits.
// Since getSimpleBinaryName() will strip the binary name of
// the immediatly enclosing class, we are now looking at a
// string that matches the regular expression "\$[0-9]*"
// followed by a simple name (considering the simple of an
// anonymous class to be the empty string).
// Remove leading "\$[0-9]*" from the name
int length = simpleName.length();
if (length < 1 || simpleName.charAt(0) != '$')
throw new InternalError("Malformed class name");
int index = 1;
while (index < length && isAsciiDigit(simpleName.charAt(index)))
index++;
// Eventually, this is the empty string iff this is an anonymous class
return simpleName.substring(index);
}
/**
* Return an informative string for the name of this type.
*
* @return an informative string for the name of this type
* @since 1.8
*/
public String getTypeName() {
if (isArray()) {
try {
Class<?> cl = this;
int dimensions = 0;
while (cl.isArray()) {
dimensions++;
cl = cl.getComponentType();
}
StringBuilder sb = new StringBuilder();
sb.append(cl.getName());
for (int i = 0; i < dimensions; i++) {
sb.append("[]");
}
return sb.toString();
} catch (Throwable e) { /*FALLTHRU*/ }
}
return getName();
}
判断字符是否是ASCII码
private static boolean isAsciiDigit(char c) {
return '0' <= c && c <= '9';
}
public String getCanonicalName() {
if (isArray()) {
String canonicalName = getComponentType().getCanonicalName();
if (canonicalName != null)
return canonicalName + "[]";
else
return null;
}
if (isLocalOrAnonymousClass())
return null;
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) { // top level class
return getName();
} else {
String enclosingName = enclosingClass.getCanonicalName();
if (enclosingName == null)
return null;
return enclosingName + "." + getSimpleName();
}
}
//判断是否是注释类型
public boolean isAnonymousClass() {
return "".equals(getSimpleName());
}
//判断是否是局部类
public boolean isLocalClass() {
return isLocalOrAnonymousClass() && !isAnonymousClass();
}
//判断是否是成员类
public boolean isMemberClass() {
return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
}
/**
* Returns the "simple binary name" of the underlying class, i.e.,
* the binary name without the leading enclosing class name.
* Returns {@code null} if the underlying class is a top level
* class.
*/
private String getSimpleBinaryName() {
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) // top level class
return null;
// Otherwise, strip the enclosing class' name
try {
return getName().substring(enclosingClass.getName().length());
} catch (IndexOutOfBoundsException ex) {
throw new InternalError("Malformed class name", ex);
}
}
//局部类和匿名类返回true
private boolean isLocalOrAnonymousClass() {
// JVM Spec 4.8.6: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
return getEnclosingMethodInfo() != null;
}
//获取该类中所有公有的成员类
@CallerSensitive
public Class<?>[] getClasses() {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
// is allowed to look at DECLARED classes because (1) it does not hand
// out anything other than public members and (2) public member access
// has already been ok'd by the SecurityManager.
return java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Class<?>[]>() {
public Class<?>[] run() {
List<Class<?>> list = new ArrayList<>();
Class<?> currentClass = Class.this;
while (currentClass != null) {
Class<?>[] members = currentClass.getDeclaredClasses();
for (int i = 0; i < members.length; i++) {
if (Modifier.isPublic(members[i].getModifiers())) {
list.add(members[i]);
}
}
currentClass = currentClass.getSuperclass();
}
return list.toArray(new Class<?>[0]);
}
});
}
//获取所有公有字段
@CallerSensitive
public Field[] getFields() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyFields(privateGetPublicFields(null));
}
//获取所有公有方法
@CallerSensitive
public Method[] getMethods() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
//获取所有公有构造器
@CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
//根据名称获取字段
@CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
//根据方法名称获取方法信息,后面的变长参数是该方法的每一个参数的对应的Class类型
@CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Method method = getMethod0(name, parameterTypes, true);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
}
return method;
}
// 根据构造器名称获取构造器信息,后面的变长参数是该构造器的每一个参数的对应的Class类型
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
//返回类中所有内部类,这里的类包括数组、接口等
@CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
return getDeclaredClasses0();
}
//返回类中成员字段
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyFields(privateGetDeclaredFields(false));
}
//返回类中成员字段
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
//返回类中所有构造器
@CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
//返回对应的字段Field对象
@CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
//返回对应的Method对象,name是方法名称,parameterTypes是对应形参
@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
}
return method;
}
//getDeclaredMethod():对给出的name获取对应的类中的方法(Method对象)
* 若不存在,则抛出NoSuchMethodException异常
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
//获取参数中指定的资源,以字节流返回
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
//返回指定的资源 url格式
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
}