Class类与JAVA反射
Class类与JAVA反射
通过反射可以访问的主要信息
包路径
getPackage() Package对象 获取该对象的存放路径;
类名称
getName() String对象 获得该类的名称;
继承类
getSuperclass() Class对象 获得该类的继承的类;
实现接口类
getInterface() Class型数组 获取该类实现的所有接口;
构造方法
getConstructors() Constructors型数组 获得所有权限为public的构造方法;
getConstructor(Class<?>...parameterTypes) Constructors 获得权限为public的指定构造方法;
getDeclaredConstructor() Constructors型数组 获得所有狗做方法,按生命顺序返回;
getDeclaredConstructor(Class<?>...parameterTypes) Constructors对象 获得指定构造法方法;
方法
getMethods() Method型数组 获得所有public权限的方法;
getMethod(String name,Class<?>...parameterTypes) Method对象 获得权限为public的指定方法;
getDeclaredMethods() Method型数组 获得所有方法,按声明顺序返回;
getDeclaredMethod(String name,Class<?>...parameterTypes) Method对象,获得指定的方法;
成员变量
getFields() Field型数组 获得所有权限为public的成员变量;
getField(String name) Field对象 活动权限为public的指定成员变量;
getDeclaredFields() Field型数组 获得所有成员变量,按声明顺序返回;
getDeclaredField(String name) Field对象 获得指定的成员变量;
内部类
getClasses() Class型数组 获得所有权限为public的内部类;
getDeclaredClasses() Class型数组 获得所有内部类;
内部类的声明类 getDeclaringClass() Class对象 如果该类为内部类,则返回它的成员类,否则返回NULL;
在通过getFields()和getMethods()方法时,将包含从超类继承道德成员变量和方法;而通过 getDeclaredFields() 和 getDeclaredMethods() 只能获得在奔雷定义的所有成员变量和方
访问构造方法
isVarArgs() 查看该构造方法是否允许带有可变数量的参数,如果允许则返回true,否则false;
getParameterTypes() 按照声明顺序以Class数组的形式获得该构造方法的各个参数类型;
getExceptionTypes() 以Class数组的形式获得该构造方法可能抛出的异常类型。
newInstance(Object...initargs) 通过该构造方法利用指定构造方法创建一个该类的对象,如果未设置,则采用无参默认构造函数
setAccessible(boolean flag) 针对private的构造方法 限制性该方法设置为true,则可以使用newInstance(Object...initargs)创建对象;
getModifiers() 获得可以解析出该构造方法所采用修饰符的整数;
public class ClassEntity {
String s;
int i, i2, i3;
private ClassEntity() {
}
protected ClassEntity(String s, int i) {
this.s = s;
this.i = i;
}
public ClassEntity(String... strings) throws NumberFormatException {
if (0 < strings.length)
i = Integer.valueOf(strings[0]);
if (1 < strings.length)
i2 = Integer.valueOf(strings[1]);
if (2 < strings.length)
i3 = Integer.valueOf(strings[2]);
}
public void print() {
System.out.println("s=" + s);
System.out.println("i=" + i);
System.out.println("i2=" + i2);
System.out.println("i3=" + i3);
}
}
public static void main(String[] args) {
ClassEntity example = new ClassEntity("10", "20", "30");
Class<? extends ClassEntity> exampleC = example.getClass();
Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) {
Constructor<?> constructor = declaredConstructors[i];
System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());
System.out.println("该构造方法的入口参数类型依次为:");
Class[] parameterTypes = constructor.getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(" " + parameterTypes[j]);
}
System.out.println("该构造方法可能抛出的异常类型为:");
Class[] exceptionTypes = constructor.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}
ClassEntity example2 = null;
while (example2 == null) {
try {
if (i == 2)
example2 = (ClassEntity) constructor.newInstance();
else if (i == 1)
example2 = (ClassEntity) constructor.newInstance("7", 5);
else {
Object[] parameters = new Object[] { new String[] {
"100", "200", "300" } };
example2 = (ClassEntity) constructor
.newInstance(parameters);
}
} catch (Exception e) {
System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
constructor.setAccessible(true);
}
}
if(example2!=null){
example2.print();
System.out.println();
}
}
}
访问成员变量
getName() 获得该成员变量的名称;
getType() 获得表示该成员变量类型的Class对象;
get(Object o) 获得指定对象obj中成员变量的值,返回Object类型;
Set(Object o,Object value) 将指定对象obj成员变量设置value值;
getInt(Object o) ;
SetInt(Object o,int value) ;
...
setAccessible(boolean flage) 此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量;
getModifiers() 获得可以解析出该成员变量所采用修饰符的整数;
public class ClassFeildEntity {
int i;
public float f;
protected boolean b;
private String s;
// private ClassEntity classEntity;
}
public static void main(String[] args) {
ClassFeildEntity example = new ClassFeildEntity();
Class exampleC = example.getClass();
// 获得所有成员变量
Field[] declaredFields = exampleC.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i]; // 遍历成员变量
// 获得成员变量名称
System.out.println("名称为:" + field.getName());
Class fieldType = field.getType(); // 获得成员变量类型
System.out.println("类型为:" + fieldType);
boolean isTurn = true;
while (isTurn) {
// 如果该成员变量的访问权限为private,则抛出异常,即不允许访问
try {
isTurn = false;
// 获得成员变量值
System.out.println("修改前的值为:" + field.get(example));
// 判断成员变量的类型是否为int型
if (fieldType.equals(int.class)) {
System.out.println("利用方法setInt()修改成员变量的值");
field.setInt(example, 168); // 为int型成员变量赋值
// 判断成员变量的类型是否为float型
} else if (fieldType.equals(float.class)) {
System.out.println("利用方法setFloat()修改成员变量的值");
// 为float型成员变量赋值
field.setFloat(example, 99.9F);
// 判断成员变量的类型是否为boolean型
} else if (fieldType.equals(boolean.class)) {
System.out.println("利用方法setBoolean()修改成员变量的值");
// 为boolean型成员变量赋值
field.setBoolean(example, true);
} else {
System.out.println("利用方法set()修改成员变量的值");
// 可以为各种类型的成员变量赋值
field.set(example, "MWQ");
}
// 获得成员变量值
System.out.println("修改后的值为:" + field.get(example));
} catch (Exception e) {
System.out.println("在设置成员变量值时抛出异常,"
+ "下面执行setAccessible()方法!");
field.setAccessible(true); // 设置为允许访问
isTurn = true;
}
}
System.out.println();
}
}
访问方法
getName() 获得该方法名称;
getParameterTypes() 按照声明顺序以Class数组的形式获得该方法的各个参数类型;
getReturnType() 以Class对象的形式获得该方法的返回值的类型;
getExceptionTypes() 以class数组的形式获得该方法可能跑出的异常类型;
invoke(Object o,Object...args) 利用指定参数args执行指定对象obj中的该方法,赶回值为Object 型;
isVarArgs() 查看该构造方法是够允许带有可变数量的参数,如果允许则返回true,否则返回false;
getModifiers() 获得可以解析出该方法所采用修饰符的整数;
setAccessible(boolean flage) ;
public class ClassMethodEntity {
static void staticMethod() {
System.out.println("执行staticMethod()方法");
}
public int publicMethod(int i) {
System.out.println("执行publicMethod()方法");
return i * 100;
}
protected int protectedMethod(String s, int i)
throws NumberFormatException {
System.out.println("执行protectedMethod()方法");
return Integer.valueOf(s) + i;
}
private String privateMethod(String... strings) {
System.out.println("执行privateMethod()方法");
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < strings.length; i++) {
stringBuffer.append(strings[i]);
}
return stringBuffer.toString();
}
}
public static void main(String[] args) {
ClassMethodEntity example = new ClassMethodEntity();
Class exampleC = example.getClass();
// 获得所有方法
Method[] declaredMethods = exampleC.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
Method method = declaredMethods[i]; // 遍历方法
System.out.println("名称为:" + method.getName()); // 获得方法名称
System.out.println("是否允许带有可变数量的参数:" + method.isVarArgs());
System.out.println("入口参数类型依次为:");
// 获得所有参数类型
Class[] parameterTypes = method.getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(" " + parameterTypes[j]);
}
// 获得方法返回值类型
System.out.println("返回值类型为:" + method.getReturnType());
System.out.println("可能抛出的异常类型有:");
// 获得方法可能抛出的所有异常类型
Class[] exceptionTypes = method.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}
boolean isTurn = true;
while (isTurn) {
// 如果该方法的访问权限为private,则抛出异常,即不允许访问
try {
isTurn = false;
if("staticMethod".equals(method.getName()))
method.invoke(example); // 执行没有入口参数的方法
else if("publicMethod".equals(method.getName()))
System.out.println("返回值为:"
+ method.invoke(example, 168)); // 执行方法
else if("protectedMethod".equals(method.getName()))
System.out.println("返回值为:"
+ method.invoke(example, "7", 5)); // 执行方法
else if("privateMethod".equals(method.getName())) {
Object[] parameters = new Object[] { new String[] {
"M", "W", "Q" } }; // 定义二维数组
System.out.println("返回值为:"
+ method.invoke(example, parameters));
}
} catch (Exception e) {
System.out.println("在执行方法时抛出异常,"
+ "下面执行setAccessible()方法!");
method.setAccessible(true); // 设置为允许访问
isTurn = true;
}
}
System.out.println();
}
}
Annotation功能
@Targer的枚举常量
ANNOTATION_TYPE 表示用于annotation类型;
TYPE 表示用于类,接口和枚举,以及annotation类型;
CONSTRUCTOR 表示用于构造方法;
FIELD 表示用于成员变量和枚举常量;
METHOD 表示用于方法;
PARAMETER 表示用于参数;
LOCAL_VARLABLE 表示用于局部变量;
PACKAGE 表示用于包;
@Retention
SOURCE 表示不便于Annotaion到类文件中;
CLASS 表示编译到Annotation类文件中,但是在运行时不加载Annotation到jvm中;
RUNTIME 表示在运行时加载Annotation到jvm中;
isAnnotation(Class<?extends Annotation> annotationClass) 用来查看是否添加了指定类型的Annotation;
getAnnotation(Class<T> annotationClass) 用来获得指定类型的Annotation;
getParameterAnnotation() 用来获得所有参数添加的Annotation,将以Annotation类的二维数组返回;
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constructor_Annotation {
String value() default "默认构造方法";
}
@Target( { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface Field_Method_Parameter_Annotation {
String describe();
Class type() default void.class;
}
public class Record {
@Field_Method_Parameter_Annotation(describe = "编号", type = int.class)
int id;
@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
String name;
@Constructor_Annotation()
public Record() {
}
@Constructor_Annotation("立即初始化构造方法")
public Record(
@Field_Method_Parameter_Annotation(describe = "编号", type = int.class)
int id,
@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
String name) {
this.id = id;
this.name = name;
}
@Field_Method_Parameter_Annotation(describe = "获得编号", type = int.class)
public int getId() {
return id;
}
@Field_Method_Parameter_Annotation(describe = "设置编号")
public void setId(
@Field_Method_Parameter_Annotation(describe = "编号", type = int.class)
int id) {
this.id = id;
}
@Field_Method_Parameter_Annotation(describe = "获得姓名", type = String.class)
public String getName() {
return name;
}
@Field_Method_Parameter_Annotation(describe = "设置姓名")
public void setName(
@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
String name) {
this.name = name;
}
}
public static void main(String[] args) {
Class recordC = null;
try {
recordC = Class.forName("com.luozy.base.ClassDemo.AnnotationDemo.Record");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("------ 构造方法的描述如下 ------");
Constructor[] declaredConstructors = recordC
.getDeclaredConstructors(); // 获得所有构造方法
for (int i = 0; i < declaredConstructors.length; i++) {
Constructor constructor = declaredConstructors[i]; // 遍历构造方法
// 查看是否具有指定类型的注释
if (constructor
.isAnnotationPresent(Constructor_Annotation.class)) {
// 获得指定类型的注释
Constructor_Annotation ca = (Constructor_Annotation) constructor
.getAnnotation(Constructor_Annotation.class);
System.out.println(constructor.getName()+"构造方法的注释信息------"+ca.value()); // 获得注释信息
}
Annotation[][] parameterAnnotations = constructor
.getParameterAnnotations(); // 获得参数的注释
for (int j = 0; j < parameterAnnotations.length; j++) {
// 获得指定参数注释的长度
int length = parameterAnnotations[j].length;
if (length == 0) // 如果长度为0则表示没有为该参数添加注释
System.out.println(" 未添加Annotation的参数");
else
for (int k = 0; k < length; k++) {
// 获得参数的注释
Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
System.out.print(" " + pa.describe()); // 获得参数描述
System.out.println(" " + pa.type()); // 获得参数类型
}
}
System.out.println();
}
System.out.println();
System.out.println("-------- 字段的描述如下 --------");
Field[] declaredFields = recordC.getDeclaredFields(); // 获得所有字段
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i]; // 遍历字段
// 查看是否具有指定类型的注释
if (field
.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {
// 获得指定类型的注释
Field_Method_Parameter_Annotation fa = field
.getAnnotation(Field_Method_Parameter_Annotation.class);
System.out.print(" " + fa.describe()); // 获得字段的描述
System.out.println(" " + fa.type()); // 获得字段的类型
}
}
System.out.println();
System.out.println("-------- 方法的描述如下 --------");
Method[] methods = recordC.getDeclaredMethods(); // 获得所有方法
for (int i = 0; i < methods.length; i++) {
Method method = methods[i]; // 遍历方法
// 查看是否具有指定类型的注释
if (method
.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {
// 获得指定类型的注释
Field_Method_Parameter_Annotation ma = method
.getAnnotation(Field_Method_Parameter_Annotation.class);
System.out.println(ma.describe()); // 获得方法的描述
System.out.println(ma.type()); // 获得方法的返回值类型
}
Annotation[][] parameterAnnotations = method
.getParameterAnnotations(); // 获得参数的注释
for (int j = 0; j < parameterAnnotations.length; j++) {
int length = parameterAnnotations[j].length; // 获得指定参数注释的长度
if (length == 0) // 如果长度为0表示没有为该参数添加注释
System.out.println(" 未添加Annotation的参数");
else
for (int k = 0; k < length; k++) {
// 获得指定类型的注释
Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
System.out.print(" " + pa.describe()); // 获得参数的描述
System.out.println(" " + pa.type()); // 获得参数的类型
}
}
System.out.println();
}
}