
源码基于android api27。
Type
public interface Type {
/**
* Returns a string describing this type, including information
* about any type parameters.
*
* @implSpec The default implementation calls {@code toString}.
*
* @return a string describing this type
* @since 1.8
* @hide Pending tests
*/
default String getTypeName() {
return toString();
}
}
Type是所有类型的父接口,主要用于反射。关于讲解,可以参见:Java中的Type详解
AnnotatedElement
public interface AnnotatedElement {
default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return getAnnotation(annotationClass) != null;
}
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
Annotation[] getAnnotations();
default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
}
default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
// Loop over all directly-present annotations looking for a matching one
for (Annotation annotation : getDeclaredAnnotations()) {
if (annotationClass.equals(annotation.annotationType())) {
// More robust to do a dynamic cast at runtime instead
// of compile-time only.
return annotationClass.cast(annotation);
}
}
return null;
}
default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
}
Annotation[] getDeclaredAnnotations();
提供了用来获取注解的方法。
GenericDeclaration
public interface GenericDeclaration extends AnnotatedElement {
//用于获取泛型参数
public TypeVariable<?>[] getTypeParameters();
}
泛型声明接口,表示用到了泛型。
Member
public interface Member {
//标识所有访问修饰符为public的成员,包括父类继承的
public static final int PUBLIC = 0;
//标识所有当前类的成员
public static final int DECLARED = 1;
//获取该成员所在的类
public Class<?> getDeclaringClass();
//获取该成员的名称
public String getName();
//获取该成员的所有修饰符,整数值每一位代表一个修饰符
public int getModifiers();
//判断该成员是否是编译器生成的。
public boolean isSynthetic();
关于修饰符的解读,可以使用
Modifier
类。
关于isSynthetic
的理解,可以参考Java的synthetic修饰词
AccessibleObject
该类是Field、Method、Constructor对象的基类,提供了在使用反射对象时,取消Java语言默认访问控制检查的能力。在使用Field、Method、Constructor执行反射操作时,会执行访问控制检查(主要是public、protected、private和默认访问权限的检查,也包括final)。
主要方法有:
//设置是否取消Java语言默认访问控制检查
public void setAccessible(boolean flag) throws SecurityException {
setAccessible0(this, flag);
}
public boolean isAccessible() {
return override;
}
比如:
public class JavaDemo {
private int value = 1;
public int getValue() {
return value;
}
public static void main(String[] args) {
try {
Class c = JavaDemo.class;
Object obj = c.newInstance();
Field f = c.getDeclaredField("value");
//f.setAccessible(true);
f.setInt(obj, 5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如上,若value有final修饰,则会抛出IllegalAccessException
,需要打开注释行才不会抛出异常。
那么问题来了,反射真的可以修改final修饰的字段的值么?可以参考 Java反射机制可以动态修改实例中final修饰的成员变量吗?
Executable
Method和Constructor的父类,简要看一下public方法:
//获取所有参数的Class类型,若包含泛型,有上限则返回其上限,否则返回Object.class。
//如:K extends Integer,返回Integer.class。
public abstract Class<?>[] getParameterTypes();
//获取参数数量
public int getParameterCount() {
throw new AbstractMethodError();
}
//获取参数的Type类型
public Type[] getGenericParameterTypes() {
return Types.getTypeArray(getMethodOrConstructorGenericInfoInternal().genericParameterTypes, false);
}
//返回Parameter数组,可以获取更加细致的信息
public Parameter[] getParameters() {
return privateGetParameters().clone();
}
//获取所有抛出的异常
public abstract Class<?>[] getExceptionTypes();
public Type[] getGenericExceptionTypes() {
return Types.getTypeArray(getMethodOrConstructorGenericInfoInternal().genericExceptionTypes, false);
}
//判断是否包含可变参数
public boolean isVarArgs() {
return (accessFlags & Modifier.VARARGS) != 0;
}
关于方法的获取,举几个例子:
public class JavaDemo<K extends Integer, M> {
public void test1(K age, M name) {
}
public void test2(String... urls) {//包含可变参数
}
public static void main(String[] args) {
try {
Class c = JavaDemo.class;
Method test1 = c.getDeclaredMethod("test1", Integer.class, Object.class);
Method test2 = c.getDeclaredMethod("test2", int.class, String[].class);
} catch (Exception e) {
e.printStackTrace();
}
}
}
网友评论