深入学习java源码之Class.forName()与 Class.getDeclaredField()
java反射
什么是反射
反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性
简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。
反射的核心是 JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
Java 反射主要提供以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
- 在运行时调用任意一个对象的方法
重点:是运行时而不是编译时
反射在运行状态把 Java 类中的各种成分映射成相应相应的 Java 类,可以动态得获取所有的属性以及动态调用任意一个方法。 1).一段java代码在程序的运行期间会经历三个阶段:source-->class-->runtime 2).Class对象 在java中用一个Class对象来表示一个java类的class阶段 Class对象封装了一个java类定义的成员变量、成员方法、构造方法、包名、类名等。 2.反射怎么用 1).获得java类的各个组成部分,首先需要获得代表java类的Class对象 获得Class对象有以下三种方式: Class.forname(className) 用于做类加载
public static Class forName(String className)
```
比如在 JDBC 开发中常用此方法加载数据库驱动:
```java
Class.forName(driver);
obj.getClass() 用于获得对象的类型
StringBuilder str = new StringBuilder("123");
Class klass = str.getClass();
类名.class 用于获得指定的类型,传参用
Class klass = int.class;
Class classInt = Integer.TYPE;
判断是否为某个类的实例
一般地,我们用 instanceof
关键字来判断是否为某个类的实例。同时我们也可以借助反射中 Class 对象的 isInstance()
方法来判断是否为某个类的实例,它是一个 native 方法:
public native boolean isInstance(Object obj);
2).反射类的构造方法,获得实例
使用Class对象的newInstance()方法来创建Class对象对应类的实例。
Class clazz = 类名.class; Constuctor con = clazz.getConstructor(new Class[]{paramClazz1,paramClazz2,.....}); con.newInstance(params....);
Class c = String.class;
Object str = c.newInstance();
先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。
//获取String所对应的Class对象
Class c = String.class;
//获取String类带一个String参数的构造器
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance("23333");
System.out.println(obj);
3).反射类的成员方法
获取某个Class对象的方法集合,主要有以下几个方法:
getDeclaredMethods
方法返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
public Method[] getDeclaredMethods() throws SecurityException
getMethods
方法返回某个类的所有公用(public)方法,包括其继承类的公用方法。
public Method[] getMethods() throws SecurityException
getMethod
方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象。
public Method getMethod(String name, Class... parameterTypes)
Method m = clazz.getMethod(methodName,new Class[]{paramClazz1,paramClazz2,.....}); m.invoke();
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test1 {
public static void test() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class c = methodClass.class;
Object object = c.newInstance();
Method[] methods = c.getMethods();
Method[] declaredMethods = c.getDeclaredMethods();
//获取methodClass类的add方法
Method method = c.getMethod("add", int.class, int.class);
//getMethods()方法获取的所有方法
System.out.println("getMethods获取的方法:");
for(Method m:methods)
System.out.println(m);
//getDeclaredMethods()方法获取的所有方法
System.out.println("getDeclaredMethods获取的方法:");
for(Method m:declaredMethods)
System.out.println(m);
}
}
class methodClass {
public final int fuck = 3;
public int add(int a,int b) {
return a+b;
}
public int sub(int a,int b) {
return a+b;
}
}
getMethods获取的方法:
public int org.ScZyhSoft.common.methodClass.add(int,int)
public int org.ScZyhSoft.common.methodClass.sub(int,int)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
getDeclaredMethods获取的方法:
public int org.ScZyhSoft.common.methodClass.add(int,int)
public int org.ScZyhSoft.common.methodClass.sub(int,int)
可以看到,通过 getMethods()
获取的方法可以获取到父类的方法,比如 java.lang.Object 下定义的各个方法。
4).反射类的属性
获取构造器信息
获取类构造器的用法与上述获取方法的用法类似。主要是通过Class类的getConstructor方法得到Constructor类的一个实例,而Constructor类有一个newInstance方法可以创建一个对象实例:
public T newInstance(Object ... initargs)
此方法可以根据传入的参数来调用对应的Constructor创建对象实例。
5).反射类的属性
getFiled
:访问公有的成员变量
getDeclaredField
:所有已声明的成员变量,但不能得到其父类的成员变量
Field field = clazz.getField(fieldName); field.setAccessible(true);//设置为可访问 filed.setObject(value); //设置值 Object value = field.get(clazz); //获得值 Object staticValue = filed.get(Class); //获得静态值
相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象(类,属性,方法)的技术。例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值,还是写两个例子让大家更直观的了解反射的使用方法:
通过类名来构造一个类的实例
Class cls_str=Class.forName("java.lang.String");
Object str=cls_str.newInstance(); //相当于String str=new String();
通过方法名来调用一个方法
String methodName="length";
Method m=cls_str.getMethod(methodName,null);
System.out.println("lengthis"+m.invoke(str,null));
//相当于System.out.println(str.length());
上面的两个例子是比较常用方法。看到上面的例子就有人要发问了:为什么要这么麻烦呢?本来一条语句就完成的事情干吗要整这么复杂?没错,在上面的例 子中确实没有必要这么麻烦。不过你想像这样一个应用程序,它支持动态的功能扩展,也就是说程序不重新启动但是可以自动加载新的功能,这个功能使用一个具体 类来表示。首先我们必须为这些功能定义一个接口类,然后我们要求所有扩展的功能类必须实现我指定的接口,这个规定了应用程序和可扩展功能之间的接口规则, 但是怎么动态加载呢?我们必须让应用程序知道要扩展的功能类的类名,比如是test.Func1,当我们把这个类名(字符串)告诉应用程序后,它就可以使 用我们第一个例子的方法来加载并启用新的功能。 6).调用方法
当我们从类中获取了一个方法后,我们就可以用 invoke()
方法来调用这个方法。invoke
方法的原型为:
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
public class test1 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class klass = methodClass.class;
//创建methodClass的实例
Object obj = klass.newInstance();
//获取methodClass类的add方法
Method method = klass.getMethod("add",int.class,int.class);
//调用method对应的方法 => add(1,4)
Object result = method.invoke(obj,1,4);
System.out.println(result);
}
}
class methodClass {
public final int fuck = 3;
public int add(int a,int b) {
return a+b;
}
public int sub(int a,int b) {
return a+b;
}
}
7).利用反射创建数组
数组在Java里是比较特殊的一种类型,它可以赋值给一个Object Reference。下面我们看一看利用反射创建数组的例子:
public static void testArray() throws ClassNotFoundException {
Class cls = Class.forName("java.lang.String");
Object array = Array.newInstance(cls,25);
//往数组里添加内容
Array.set(array,0,"hello");
Array.set(array,1,"Java");
Array.set(array,2,"fuck");
Array.set(array,3,"Scala");
Array.set(array,4,"Clojure");
//获取某一项的内容
System.out.println(Array.get(array,3));
}
其中的Array类为java.lang.reflect.Array类。我们通过Array.newInstance()创建数组对象,它的原型是:
public static Object newInstance(Class componentType, int length)
throws NegativeArraySizeException {
return newArray(componentType, length);
}
而 newArray
方法是一个 native 方法,它在 HotSpot JVM 里的具体实现我们后边再研究,这里先把源码贴出来:
private static native Object newArray(Class componentType, int length)
throws NegativeArraySizeException;
反射的一些注意事项
由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。
另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
java源码
Modifier and TypeMethod and Description 类
forName(String className)
返回与给定字符串名称的类或接口相关联的 类
对象。
static 类
forName(String name, boolean initialize, ClassLoader loader)
使用给定的类加载器返回与给定字符串名称的类或接口相关联的 类
对象。
AnnotatedType[]
getAnnotatedInterfaces()
返回一个 AnnotatedType
对象的数组, AnnotatedType
使用类型指定由此 AnnotatedType
对象表示的实体的超级 类
。
AnnotatedType
getAnnotatedSuperclass()
返回一个 AnnotatedType
对象,该对象表示使用类型来指定由此 类
对象表示的实体的 类
类。
A
getAnnotation(类 annotationClass)
返回该元素的,如果这样的注释 ,否则返回null指定类型的注释。
Annotation[]
getAnnotations()
返回此元素上 存在的注释。
A[]
getAnnotationsByType(类 annotationClass)
返回与此元素相关 联的注释 。
String
getCanonicalName()
返回由Java语言规范定义的基础类的规范名称。
类[]
getClasses()
返回包含一个数组 类
表示所有的公共类和由此表示的类的成员接口的对象 类
对象。
ClassLoader
getClassLoader()
返回类的类加载器。
类
getComponentType()
返回 类
数组的组件类型的Class。
Constructor
getConstructor(类... parameterTypes)
返回一个 Constructor
对象,该对象反映 Constructor
对象表示的类的指定的公共 类
函数。
Constructor[]
getConstructors()
返回包含一个数组 Constructor
对象反射由此表示的类的所有公共构造 类
对象。
A
getDeclaredAnnotation(类 annotationClass)
如果这样的注释 直接存在 ,则返回指定类型的元素注释,否则返回null。
Annotation[]
getDeclaredAnnotations()
返回 直接存在于此元素上的注释。
A[]
getDeclaredAnnotationsByType(类 annotationClass)
如果此类注释 直接存在或 间接存在,则返回该元素的注释(指定类型)。
类[]
getDeclaredClasses()
返回一个反映所有被这个 类
对象表示的类的成员声明的类和 类
对象的数组。
Constructor
getDeclaredConstructor(类... parameterTypes)
返回一个 Constructor
对象,该对象反映 Constructor
对象表示的类或接口的指定 类
函数。
Constructor[]
getDeclaredConstructors()
返回一个反映 Constructor
对象表示的类声明的所有 Constructor
对象的数组 类
。
Field
getDeclaredField(String name)
返回一个 Field
对象,它反映此表示的类或接口的指定已声明字段 类
对象。
Field[]
getDeclaredFields()
返回的数组 Field
对象反映此表示的类或接口声明的所有字段 类
对象。
方法
getDeclaredMethod(String name, 类... parameterTypes)
返回一个 方法
对象,它反映此表示的类或接口的指定声明的方法 类
对象。
方法[]
getDeclaredMethods()
返回包含一个数组 方法
对象反射的类或接口的所有声明的方法,通过此表示 类
对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
类
getDeclaringClass()
如果由此 类
对象表示的类或接口是另一个类的成员,则返回表示其声明的类的 类
对象。
类
getEnclosingClass()
返回底层类的即时封闭类。
Constructor
getEnclosingConstructor()
如果此类
对象表示构造函数中的本地或匿名类,则返回表示底层类的立即封闭构造函数的Constructor
对象。
方法
getEnclosingMethod()
如果此类
对象表示方法中的本地或匿名类,则返回表示基础类的即时封闭方法的方法
对象。
T[]
getEnumConstants()
返回此枚举类的元素,如果此Class对象不表示枚举类型,则返回null。
Field
getField(String name)
返回一个 Field
对象,它反映此表示的类或接口的指定公共成员字段 类
对象。
Field[]
getFields()
返回包含一个数组 Field
对象反射由此表示的类或接口的所有可访问的公共字段 类
对象。
Type[]
getGenericInterfaces()
返回 Type
表示通过由该对象所表示的类或接口直接实现的接口秒。
Type
getGenericSuperclass()
返回 Type
表示此所表示的实体(类,接口,基本类型或void)的直接超类 类
。
类[]
getInterfaces()
确定由该对象表示的类或接口实现的接口。
方法
getMethod(String name, 类... parameterTypes)
返回一个 方法
对象,它反映此表示的类或接口的指定公共成员方法 类
对象。
方法[]
getMethods()
返回包含一个数组 方法
对象反射由此表示的类或接口的所有公共方法 类
对象,包括那些由类或接口和那些从超类和超接口继承的声明。
int
getModifiers()
返回此类或接口的Java语言修饰符,以整数编码。
String
getName()
返回由 类
对象表示的实体(类,接口,数组类,原始类型或空白)的名称,作为 String
。
软件包
getPackage()
获取此类的包。
ProtectionDomain
getProtectionDomain()
返回 ProtectionDomain
。
URL
getResource(String name)
查找具有给定名称的资源。
InputStream
getResourceAsStream(String name)
查找具有给定名称的资源。
Object[]
getSigners()
获得这个类的签名者。
String
getSimpleName()
返回源代码中给出的基础类的简单名称。
类[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append(' caller)
throws ClassNotFoundException;
@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 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() {
public Void run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw (InstantiationException)
new InstantiationException(getName()).initCause(e);
}
}
Constructor 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 cachedConstructor;
private volatile transient Class newInstanceCallerCache;
public native boolean isInstance(Object obj);
public native boolean isAssignableFrom(Class cls);
public native boolean isInterface();
public native boolean isArray();
public native boolean isPrimitive();
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; }
private final ClassLoader classLoader;
@SuppressWarnings("unchecked")
public TypeVariable[] getTypeParameters() {
ClassRepository info = getGenericInfo();
if (info != null)
return (TypeVariable[])info.getTypeParameters();
else
return (TypeVariable[])new TypeVariable[0];
}
public native Class[] getInterfaces() {
ReflectionData 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();
}
public native Class getComponentType();
public native int getModifiers();
public native Object[] getSigners();
native void setSigners(Object[] signers);
@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() && "".equals(name); }
boolean isMethod() { return !isPartial() && !isConstructor() && !"".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;
}
@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");
}
}
@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;
}
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
}
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);
}
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();
}
private static boolean isAsciiDigit(char c) {
return '0' [] getClasses() {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
return java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction[] run() {
List 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;
}
@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;
}
@CallerSensitive
public Constructor 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));
}
@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;
}
@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;
}
@CallerSensitive
public Constructor 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);
}
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);
}
/** protection domain returned when the internal domain is null */
private static java.security.ProtectionDomain allPermDomain;
public java.security.ProtectionDomain getProtectionDomain() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
}
java.security.ProtectionDomain pd = getProtectionDomain0();
if (pd == null) {
if (allPermDomain == null) {
java.security.Permissions perms =
new java.security.Permissions();
perms.add(SecurityConstants.ALL_PERMISSION);
allPermDomain =
new java.security.ProtectionDomain(null, perms);
}
pd = allPermDomain;
}
return pd;
}
private native java.security.ProtectionDomain getProtectionDomain0();
static native Class getPrimitiveClass(String name);
private void checkMemberAccess(int which, Class caller, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
/* Default policy allows access to all {@link Member#PUBLIC} members,
* as well as access to classes that have the same class loader as the caller.
* In all other cases, it requires RuntimePermission("accessDeclaredMembers")
* permission.
*/
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
final ClassLoader cl = getClassLoader0();
if (which != Member.PUBLIC) {
if (ccl != cl) {
s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
}
this.checkPackageAccess(ccl, checkProxyInterfaces);
}
}
private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
final ClassLoader cl = getClassLoader0();
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
// skip the package access check on a proxy class in default proxy package
String pkg = name.substring(0, i);
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
}
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}
/**
* Atomic operations support.
*/
private static class Atomic {
// initialize Unsafe machinery here, since we need to call Class.class instance method
// and have to avoid calling it in the static initializer of the Class class...
private static final Unsafe unsafe = Unsafe.getUnsafe();
// offset of Class.reflectionData instance field
private static final long reflectionDataOffset;
// offset of Class.annotationType instance field
private static final long annotationTypeOffset;
// offset of Class.annotationData instance field
private static final long annotationDataOffset;
static {
Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
annotationTypeOffset = objectFieldOffset(fields, "annotationType");
annotationDataOffset = objectFieldOffset(fields, "annotationData");
}
private static long objectFieldOffset(Field[] fields, String fieldName) {
Field field = searchFields(fields, fieldName);
if (field == null) {
throw new Error("No " + fieldName + " field found in java.lang.Class");
}
return unsafe.objectFieldOffset(field);
}
static boolean casReflectionData(Class clazz,
SoftReference oldData,
SoftReference newData) {
return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
}
static boolean casAnnotationType(Class clazz,
AnnotationType oldType,
AnnotationType newType) {
return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
}
static boolean casAnnotationData(Class clazz,
AnnotationData oldData,
AnnotationData newData) {
return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData);
}
}
// Caches for certain reflective results
private static boolean useCaches = true;
// reflection data that might get invalidated when JVM TI RedefineClasses() is called
private static class ReflectionData {
volatile Field[] declaredFields;
volatile Field[] publicFields;
volatile Method[] declaredMethods;
volatile Method[] publicMethods;
volatile Constructor[] declaredConstructors;
volatile Constructor[] publicConstructors;
// Intermediate results for getFields and getMethods
volatile Field[] declaredPublicFields;
volatile Method[] declaredPublicMethods;
volatile Class[] interfaces;
// Value of classRedefinedCount when we created this ReflectionData instance
final int redefinedCount;
ReflectionData(int redefinedCount) {
this.redefinedCount = redefinedCount;
}
}
private volatile transient SoftReference reflectionData;
// Incremented by the VM on each call to JVM TI RedefineClasses()
// that redefines this class or a superclass.
private volatile transient int classRedefinedCount = 0;
// Lazily create and cache ReflectionData
private ReflectionData reflectionData() {
SoftReference reflectionData = this.reflectionData;
int classRedefinedCount = this.classRedefinedCount;
ReflectionData rd;
if (useCaches &&
reflectionData != null &&
(rd = reflectionData.get()) != null &&
rd.redefinedCount == classRedefinedCount) {
return rd;
}
// else no SoftReference or cleared SoftReference or stale ReflectionData
// -> create and replace new instance
return newReflectionData(reflectionData, classRedefinedCount);
}
private ReflectionData newReflectionData(SoftReference oldReflectionData,
int classRedefinedCount) {
if (!useCaches) return null;
while (true) {
ReflectionData rd = new ReflectionData(classRedefinedCount);
// try to CAS it...
if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference(rd))) {
return rd;
}
// else retry
oldReflectionData = this.reflectionData;
classRedefinedCount = this.classRedefinedCount;
if (oldReflectionData != null &&
(rd = oldReflectionData.get()) != null &&
rd.redefinedCount == classRedefinedCount) {
return rd;
}
}
}
// Generic signature handling
private native String getGenericSignature0();
// Generic info repository; lazily initialized
private volatile transient ClassRepository genericInfo;
// accessor for factory
private GenericsFactory getFactory() {
// create scope and factory
return CoreReflectionFactory.make(this, ClassScope.make(this));
}
// accessor for generic info repository;
// generic info is lazily initialized
private ClassRepository getGenericInfo() {
ClassRepository genericInfo = this.genericInfo;
if (genericInfo == null) {
String signature = getGenericSignature0();
if (signature == null) {
genericInfo = ClassRepository.NONE;
} else {
genericInfo = ClassRepository.make(signature, getFactory());
}
this.genericInfo = genericInfo;
}
return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
}
// Annotations handling
native byte[] getRawAnnotations();
// Since 1.8
native byte[] getRawTypeAnnotations();
static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
}
native ConstantPool getConstantPool();
private Field[] privateGetDeclaredFields(boolean publicOnly) {
checkInitted();
Field[] res;
ReflectionData rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;
if (res != null) return res;
}
// No cached value available; request value from VM
res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
if (rd != null) {
if (publicOnly) {
rd.declaredPublicFields = res;
} else {
rd.declaredFields = res;
}
}
return res;
}
private Field[] privateGetPublicFields(Set c : getInterfaces()) {
if (!traversedInterfaces.contains(c)) {
traversedInterfaces.add(c);
addAll(fields, c.privateGetPublicFields(traversedInterfaces));
}
}
// Direct superclass, recursively
if (!isInterface()) {
Class c = getSuperclass();
if (c != null) {
addAll(fields, c.privateGetPublicFields(traversedInterfaces));
}
}
res = new Field[fields.size()];
fields.toArray(res);
if (rd != null) {
rd.publicFields = res;
}
return res;
}
private static void addAll(Collection c, Field[] o) {
for (int i = 0; i < o.length; i++) {
c.add(o[i]);
}
}
private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) {
checkInitted();
Constructor[] res;
ReflectionData rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;
if (res != null) return res;
}
// No cached value available; request value from VM
if (isInterface()) {
@SuppressWarnings("unchecked")
Constructor[] temporaryRes = (Constructor[]) new Constructor[0];
res = temporaryRes;
} else {
res = getDeclaredConstructors0(publicOnly);
}
if (rd != null) {
if (publicOnly) {
rd.publicConstructors = res;
} else {
rd.declaredConstructors = res;
}
}
return res;
}
private Method[] privateGetDeclaredMethods(boolean publicOnly) {
checkInitted();
Method[] res;
ReflectionData rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
if (res != null) return res;
}
// No cached value available; request value from VM
res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
if (rd != null) {
if (publicOnly) {
rd.declaredPublicMethods = res;
} else {
rd.declaredMethods = res;
}
}
return res;
}
static class MethodArray {
// Don't add or remove methods except by add() or remove() calls.
private Method[] methods;
private int length;
private int defaults;
MethodArray() {
this(20);
}
MethodArray(int initialSize) {
if (initialSize < 2)
throw new IllegalArgumentException("Size should be 2 or more");
methods = new Method[initialSize];
length = 0;
defaults = 0;
}
boolean hasDefaults() {
return defaults != 0;
}
void add(Method m) {
if (length == methods.length) {
methods = Arrays.copyOf(methods, 2 * methods.length);
}
methods[length++] = m;
if (m != null && m.isDefault())
defaults++;
}
void addAll(Method[] ma) {
for (int i = 0; i < ma.length; i++) {
add(ma[i]);
}
}
void addAll(MethodArray ma) {
for (int i = 0; i < ma.length(); i++) {
add(ma.get(i));
}
}
void addIfNotPresent(Method newMethod) {
for (int i = 0; i < length; i++) {
Method m = methods[i];
if (m == newMethod || (m != null && m.equals(newMethod))) {
return;
}
}
add(newMethod);
}
void addAllIfNotPresent(MethodArray newMethods) {
for (int i = 0; i < newMethods.length(); i++) {
Method m = newMethods.get(i);
if (m != null) {
addIfNotPresent(m);
}
}
}
/* Add Methods declared in an interface to this MethodArray.
* Static methods declared in interfaces are not inherited.
*/
void addInterfaceMethods(Method[] methods) {
for (Method candidate : methods) {
if (!Modifier.isStatic(candidate.getModifiers())) {
add(candidate);
}
}
}
int length() {
return length;
}
Method get(int i) {
return methods[i];
}
Method getFirst() {
for (Method m : methods)
if (m != null)
return m;
return null;
}
void removeByNameAndDescriptor(Method toRemove) {
for (int i = 0; i < length; i++) {
Method m = methods[i];
if (m != null && matchesNameAndDescriptor(m, toRemove)) {
remove(i);
}
}
}
private void remove(int i) {
if (methods[i] != null && methods[i].isDefault())
defaults--;
methods[i] = null;
}
private boolean matchesNameAndDescriptor(Method m1, Method m2) {
return m1.getReturnType() == m2.getReturnType() &&
m1.getName() == m2.getName() && // name is guaranteed to be interned
arrayContentsEq(m1.getParameterTypes(),
m2.getParameterTypes());
}
void compactAndTrim() {
int newPos = 0;
// Get rid of null slots
for (int pos = 0; pos < length; pos++) {
Method m = methods[pos];
if (m != null) {
if (pos != newPos) {
methods[newPos] = m;
}
newPos++;
}
}
if (newPos != methods.length) {
methods = Arrays.copyOf(methods, newPos);
}
}
void removeLessSpecifics() {
if (!hasDefaults())
return;
for (int i = 0; i < length; i++) {
Method m = get(i);
if (m == null || !m.isDefault())
continue;
for (int j = 0; j < length; j++) {
if (i == j)
continue;
Method candidate = get(j);
if (candidate == null)
continue;
if (!matchesNameAndDescriptor(m, candidate))
continue;
if (hasMoreSpecificClass(m, candidate))
remove(j);
}
}
}
Method[] getArray() {
return methods;
}
// Returns true if m1 is more specific than m2
static boolean hasMoreSpecificClass(Method m1, Method m2) {
Class m1Class = m1.getDeclaringClass();
Class m2Class = m2.getDeclaringClass();
return m1Class != m2Class && m2Class.isAssignableFrom(m1Class);
}
}
private Method[] privateGetPublicMethods() {
checkInitted();
Method[] res;
ReflectionData rd = reflectionData();
if (rd != null) {
res = rd.publicMethods;
if (res != null) return res;
}
// No cached value available; compute value recursively.
// Start by fetching public declared methods
MethodArray methods = new MethodArray();
{
Method[] tmp = privateGetDeclaredMethods(true);
methods.addAll(tmp);
}
// Now recur over superclass and direct superinterfaces.
// Go over superinterfaces first so we can more easily filter
// out concrete implementations inherited from superclasses at
// the end.
MethodArray inheritedMethods = new MethodArray();
for (Class i : getInterfaces()) {
inheritedMethods.addInterfaceMethods(i.privateGetPublicMethods());
}
if (!isInterface()) {
Class c = getSuperclass();
if (c != null) {
MethodArray supers = new MethodArray();
supers.addAll(c.privateGetPublicMethods());
// Filter out concrete implementations of any
// interface methods
for (int i = 0; i < supers.length(); i++) {
Method m = supers.get(i);
if (m != null &&
!Modifier.isAbstract(m.getModifiers()) &&
!m.isDefault()) {
inheritedMethods.removeByNameAndDescriptor(m);
}
}
// Insert superclass's inherited methods before
// superinterfaces' to satisfy getMethod's search
// order
supers.addAll(inheritedMethods);
inheritedMethods = supers;
}
}
// Filter out all local methods from inherited ones
for (int i = 0; i < methods.length(); i++) {
Method m = methods.get(i);
inheritedMethods.removeByNameAndDescriptor(m);
}
methods.addAllIfNotPresent(inheritedMethods);
methods.removeLessSpecifics();
methods.compactAndTrim();
res = methods.getArray();
if (rd != null) {
rd.publicMethods = res;
}
return res;
}
private static Field searchFields(Field[] fields, String name) {
String internedName = name.intern();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName() == internedName) {
return getReflectionFactory().copyField(fields[i]);
}
}
return null;
}
private Field getField0(String name) throws NoSuchFieldException {
// Note: the intent is that the search algorithm this routine
// uses be equivalent to the ordering imposed by
// privateGetPublicFields(). It fetches only the declared
// public fields for each class, however, to reduce the number
// of Field objects which have to be created for the common
// case where the field being requested is declared in the
// class which is being queried.
Field res;
// Search declared public fields
if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
return res;
}
// Direct superinterfaces, recursively
Class[] interfaces = getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
Class c = interfaces[i];
if ((res = c.getField0(name)) != null) {
return res;
}
}
// Direct superclass, recursively
if (!isInterface()) {
Class c = getSuperclass();
if (c != null) {
if ((res = c.getField0(name)) != null) {
return res;
}
}
}
return null;
}
private static Method searchMethods(Method[] methods,
String name,
Class[] parameterTypes)
{
Method res = null;
String internedName = name.intern();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName() == internedName
&& arrayContentsEq(parameterTypes, m.getParameterTypes())
&& (res == null
|| res.getReturnType().isAssignableFrom(m.getReturnType())))
res = m;
}
return (res == null ? res : getReflectionFactory().copyMethod(res));
}
private Method getMethod0(String name, Class[] parameterTypes, boolean includeStaticMethods) {
MethodArray interfaceCandidates = new MethodArray(2);
Method res = privateGetMethodRecursive(name, parameterTypes, includeStaticMethods, interfaceCandidates);
if (res != null)
return res;
// Not found on class or superclass directly
interfaceCandidates.removeLessSpecifics();
return interfaceCandidates.getFirst(); // may be null
}
private Method privateGetMethodRecursive(String name,
Class[] parameterTypes,
boolean includeStaticMethods,
MethodArray allInterfaceCandidates) {
Method res;
// Search declared public methods
if ((res = searchMethods(privateGetDeclaredMethods(true),
name,
parameterTypes)) != null) {
if (includeStaticMethods || !Modifier.isStatic(res.getModifiers()))
return res;
}
// Search superclass's methods
if (!isInterface()) {
Class[] interfaces = getInterfaces();
for (Class c : interfaces)
if ((res = c.getMethod0(name, parameterTypes, false)) != null)
allInterfaceCandidates.add(res);
// Not found
return null;
}
private Constructor getConstructor0(Class[] parameterTypes,
int which) throws NoSuchMethodException
{
Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
for (Constructor constructor : constructors) {
if (arrayContentsEq(parameterTypes,
constructor.getParameterTypes())) {
return getReflectionFactory().copyConstructor(constructor);
}
}
throw new NoSuchMethodException(getName() + "." + argumentTypesToString(parameterTypes));
}
private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
if (a1 == null) {
return a2 == null || a2.length == 0;
}
if (a2 == null) {
return a1.length == 0;
}
if (a1.length != a2.length) {
return false;
}
for (int i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
return false;
}
}
return true;
}
private static Field[] copyFields(Field[] arg) {
Field[] out = new Field[arg.length];
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < arg.length; i++) {
out[i] = fact.copyField(arg[i]);
}
return out;
}
private static Method[] copyMethods(Method[] arg) {
Method[] out = new Method[arg.length];
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < arg.length; i++) {
out[i] = fact.copyMethod(arg[i]);
}
return out;
}
private static Constructor[] copyConstructors(Constructor[] arg) {
Constructor[] out = arg.clone();
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < out.length; i++) {
out[i] = fact.copyConstructor(out[i]);
}
return out;
}
private native Field[] getDeclaredFields0(boolean publicOnly);
private native Method[] getDeclaredMethods0(boolean publicOnly);
private native Constructor[] getDeclaredConstructors0(boolean publicOnly);
private native Class[] getDeclaredClasses0();
private static String argumentTypesToString(Class[] argTypes) {
StringBuilder buf = new StringBuilder();
buf.append("(");
if (argTypes != null) {
for (int i = 0; i < argTypes.length; i++) {
if (i > 0) {
buf.append(", ");
}
Class c = argTypes[i];
buf.append((c == null) ? "null" : c.getName());
}
}
buf.append(")");
return buf.toString();
}
/** use serialVersionUID from JDK 1.1 for interoperability */
private static final long serialVersionUID = 3206093459760846163L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
public boolean desiredAssertionStatus() {
ClassLoader loader = getClassLoader();
// If the loader is null this is a system class, so ask the VM
if (loader == null)
return desiredAssertionStatus0(this);
// If the classloader has been initialized with the assertion
// directives, ask it. Otherwise, ask the VM.
synchronized(loader.assertionLock) {
if (loader.classAssertionStatus != null) {
return loader.desiredAssertionStatus(getName());
}
}
return desiredAssertionStatus0(this);
}
// Retrieves the desired assertion status of this class from the VM
private static native boolean desiredAssertionStatus0(Class clazz);
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
// the ENUM bit set; classes for specialized enum constants
// don't do the former.
return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
// Fetches the factory for reflective objects
private static ReflectionFactory getReflectionFactory() {
if (reflectionFactory == null) {
reflectionFactory =
java.security.AccessController.doPrivileged
(new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
}
return reflectionFactory;
}
private static ReflectionFactory reflectionFactory;
// To be able to query system properties as soon as they're available
private static boolean initted = false;
private static void checkInitted() {
if (initted) return;
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
if (System.out == null) {
// java.lang.System not yet fully initialized
return null;
}
// Doesn't use Boolean.getBoolean to avoid class init.
String val =
System.getProperty("sun.reflect.noCaches");
if (val != null && val.equals("true")) {
useCaches = false;
}
initted = true;
return null;
}
});
}
public T[] getEnumConstants() {
T[] values = getEnumConstantsShared();
return (values != null) ? values.clone() : null;
}
T[] getEnumConstantsShared() {
if (enumConstants == null) {
if (!isEnum()) return null;
try {
final Method values = getMethod("values");
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Void run() {
values.setAccessible(true);
return null;
}
});
@SuppressWarnings("unchecked")
T[] temporaryConstants = (T[])values.invoke(null);
enumConstants = temporaryConstants;
}
// These can happen when users concoct enum-like classes
// that don't comply with the enum spec.
catch (InvocationTargetException | NoSuchMethodException |
IllegalAccessException ex) { return null; }
}
return enumConstants;
}
private volatile transient T[] enumConstants = null;
Map enumConstantDirectory() {
if (enumConstantDirectory == null) {
T[] universe = getEnumConstantsShared();
if (universe == null)
throw new IllegalArgumentException(
getName() + " is not an enum type");
Map m = new HashMap(2 * universe.length);
for (T constant : universe)
m.put(((Enum)constant).name(), constant);
enumConstantDirectory = m;
}
return enumConstantDirectory;
}
private volatile transient Map enumConstantDirectory = null;
@SuppressWarnings("unchecked")
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj;
}
private String cannotCastMsg(Object obj) {
return "Cannot cast " + obj.getClass().getName() + " to " + getName();
}
@SuppressWarnings("unchecked")
public Class superClass = getSuperclass();
Map
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?