反射
反射是将类抽象为一个Class对象。将类看成对象,分析它的构造方法,成员变量,方法以及内部类。
对类的分析,是将类抽象为Class对象;对构造方法的分析,是将构造方法抽象为Constructor类的对象;对成员变量的分析,是将变量抽象为Feild类的对象;对方法的分析,是将方法抽象为Method类的对象。
举个例子:
public class Student {
public String name;//定义学生姓名
private int age;//定义学生年龄
private String sex;//定义学生性别
//获得学生姓名的方法
public String getName() {
return name;
}
//学生姓名赋值的方法
public void setName(String name) {
this.name = name;
}
//获得学生年龄的方法
public int getAge() {
return age;
}
//注意,这里没有为学生年龄赋值的方法,学生年龄为私有类型。
//获得学生性别的方法
public String getSex() {
return sex;
}
//学生性别赋值的方法
public void setSex(String sex) {
this.sex = sex;
}
}
public class Test {
public static void main(String[] args) {
Class<Student> clazz =Student.class;
try {
/Class Field Method的使用。
//获得Student类的name属性对象。
Field field1 = clazz.getDeclaredField("name");
//返回name字段的修饰符
System.out.println(field1.getModifiers());
//返回name字段的类型
System.out.println(field1.getType());
//返回name字段的名称
System.out.println(field1.getName());
//获得Student类的所有属性对象。
Field[] field2 = clazz.getDeclaredFields();
//遍历所有属性
for (Field field : field2) {
System.out.println(field.getName());
System.out.println(field.getType());
System.out.println(field.getModifiers());
}
//为学生对象zhangsan没有set方法的私有类型age赋值
Student zhangsan = new Student();
//获得age属性的对象
Field age = clazz.getDeclaredField("age");
//取消对age属性的修饰符的检查访问,以便为age属性赋值
age.setAccessible(true);
//为age属性赋值
age.set(zhangsan, 18);
//回复对age属性的修饰符的检查访问
age.setAccessible(false);
System.out.println(zhangsan.getAge());
//Method 的使用
Method method1= clazz.getDeclaredMethod("getName");
System.out.println(method1.getModifiers());
注解(Annotation)
注解的定义形式:
@interface 注解名{
<成员类型> <成员名称>() default "<默认值>";
……
}
下面这个例子定义了一个注解,注解名为MyAnotation,注解包含一个成员是int型的value()。@Retention表示注解的应用范围,注解的应用范围通常用RetentionPolicy中的枚举常量表示,这个例子中用的RetentionPolicy中的RUNTIME常量,表示在运行时加载注解到虚拟机,有效的范围最大。@Target表示次注解适用于变量类型,并且可为int类型的变量赋值。
此图片摘自博客园的……@黑色幽默Lion
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnotation {
int value();
}
import java.lang.reflect.Field;
public class Student {
private String name;
@MyAnotation(value =18)
private int age;
Student(){
Class clazz = Student.class;
try {
//获取age属性对象
Field field = clazz.getDeclaredField("age");
//创建注解对象,获取age属性的注解
MyAnotation ma = field.getAnnotation(MyAnotation.class);
//判断获得的注解对象是否为空
if(ma!=null){
//为age赋值
int i = ma.value();
field.setAccessible(true);
field.set(this, i);
field.setAccessible(false);
}
} catch (NoSuchFieldException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
本文介绍了Java反射机制的基本概念及使用方式,并通过实例演示了如何利用反射操作类的成员变量及方法。此外,还详细解释了注解的定义与应用,展示了如何使用自定义注解来扩展程序的功能。
997

被折叠的 条评论
为什么被折叠?



