反射和四种元注解
反射
反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性。
反射的作用:
Java反射机制提供了以下的功能 在运行时获取类的修饰符,包名,类名,实现的接口,继承的父类
在运行时获取类的所有属性名,修饰符,属性类型
在运行时获取所有方法,方法的返回值类型,方法名,方法参数数量,方法参数类型
在运行时调用加载类的方法
Java中的四种元注解:
@Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target:注解的作用目标
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
一、自定义注解
//自定义注解
//注释可用在类、成员变量、方法、构造函数上
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})
@Documented//文档注解
@Inherited//可继承,允许子类继承父类的注解
@Retention(RetentionPolicy.RUNTIME)//注解保留在的位置
public @interface StudentAnnotation {
String name();
int num();
}
二、创建一个对象类
@StudentAnnotation(name = "我是类", num =123)
public class Student extends Thread implements Runnable,Callable{
@StudentAnnotation(name = "我是成员变量", num =121)
private String stuName;
private int age;
private String stuNumb;
@StudentAnnotation(name = "我是带参构造函数", num =121)
public Student(String stuName, int age, String stuNumb) {
this.stuName = stuName;
this.age = age;
this.stuNumb = stuNumb;
}
@StudentAnnotation(name = "我是无参构造函数", num =126)
public Student() {
}
@StudentAnnotation(name = "我是方法showInf", num =122)
public String showInf(){
return "姓名是:"+stuName+",年龄是:"+age+",学号是:"+stuNumb;
}
@StudentAnnotation(name = "我是方法test", num =122)
private void test(){
System.out.println("我是私有方法!test()");
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getStuNumb() {
return stuNumb;
}
public void setStuNumb(String stuNumb) {
this.stuNumb = stuNumb;
}
@Override
public void run() {
// TODO Auto-generated method stub
}
@Override
public Object call() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
三、创建一个测试类,通过反射获取类的信息及属性,方法,构造函数,注解
public class TestCase {
public static void main(String[] args) throws Exception {
TestCase tc=new TestCase();
//三种获得类名的方式
Class cla1=Class.forName("ldl.fanshe619.Student");
Class cla2=Student.class;
Class cla3=new Student().getClass();
System.out.println("类名是:"+cla1);
tc.getSuperClassOrInterface(cla1);
System.out.println("\n--------------------------");
tc.getClassAndModifies(cla1);
System.out.println("--------------------------");
tc.getFields(cla1);
System.out.println("--------------------------");
tc.getMethods(cla1);
System.out.println("--------------------------");
tc.getConstructors(cla1);
System.out.println("--------------------------");
tc.getAnnotation(cla1);
}
//1.获取类的父类和实现的接口
public void getSuperClassOrInterface(Class cla) throws Exception{
String supname=cla.getSuperclass().getName();
System.out.println("继承的父类是:"+supname);
Class[] c1=cla.getInterfaces();
System.out.print("实现的接口有:");
for(Class ca:c1){
System.out.print(ca+",");
}
}
//2.获取类名和访问修饰符
public void getClassAndModifies(Class cla){
//获取类的访问修饰符
int a=cla.getModifiers();
Modifier.toString(a);
System.out.println("类的修饰符是:"+Modifier.toString(a));
}
//3.获取所有成员变量
public void getFields(Class cla) throws Exception{
//获得所有变量的信息
Field[] f=cla.getDeclaredFields();
System.out.println("所有成员变量:");
for(Field fe:f){
System.out.println(Modifier.toString(fe.getModifiers())+" "+fe.getType().getSimpleName()+" "+fe.getName());
}
//获取单个变量的信息
Field fe=cla.getDeclaredField("stuName");
//System.out.println(fe);
//创建Class对象
Object obj=cla.newInstance();
//屏蔽变量的私有特性,并赋值
fe.setAccessible(true);
//没有屏蔽私有属性的变量会赋值失败
fe.set(obj, "张三");
Student st=(Student) obj;
System.out.println("学生名为:"+st.getStuName());
}
//4.获取所有成员方法
public void getMethods(Class cla) throws Exception{
//获取自己类中的方法(所有的公共方法和私有方法)
Method[] me=cla.getDeclaredMethods();
//获取自己类中和所有父类中的所有公共方法
Method[] me2=cla.getMethods();
System.out.println("所有成员方法:");
for(Method meth:me){
System.out.println(Modifier.toString(meth.getModifiers())+" "+meth.getReturnType().getSimpleName()+" "+
meth.getName()+"()"+"{}");
}
//获取test方法
Method mth=cla.getDeclaredMethod("test");
//屏蔽方法的私有属性
mth.setAccessible(true);
//创建对象
Object obj=cla.newInstance();
//实现对test方法的调用
mth.invoke(obj);
}
//5.获取构造函数
public void getConstructors(Class cla) throws Exception{
//获取所有构造函数
Constructor[] con=cla.getConstructors();
for(Constructor cons:con){
System.out.println(cons);
}
//获取定义参数的构造函数
Constructor constr=cla.getConstructor(String.class,int.class,String.class);
Object obj=constr.newInstance("王庆",18,"12345");
Student stu=(Student) obj;
System.out.println(stu.showInf());
}
//6.获取注解
public void getAnnotation(Class cla) throws Exception{
StudentAnnotation stu1=(StudentAnnotation) cla.getAnnotation(StudentAnnotation.class);
System.out.println("类的注解是:"+stu1);
StudentAnnotation stu2=cla.getDeclaredField("stuName").getAnnotation(StudentAnnotation.class);
System.out.println("成员变量的注解是:"+stu2);
StudentAnnotation stu3=cla.getDeclaredMethod("test").getAnnotation(StudentAnnotation.class);
System.out.println("方法的注解是:"+stu3);
StudentAnnotation stu4=(StudentAnnotation)cla.getConstructor().getAnnotation(StudentAnnotation.class);
System.out.println("构造函数的注解是:"+stu4);
}
}
转载于//www.cnblogs.com/TFE-HardView/p/11052392.html
还没有评论,来说两句吧...