反射和四种元注解

Myth丶恋晨 2021-12-22 02:49 338阅读 0赞

反射

反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性。

反射的作用:

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:说明子类可以继承父类中的该注解

一、自定义注解

  1. //自定义注解
  2. //注释可用在类、成员变量、方法、构造函数上
  3. @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})
  4. @Documented//文档注解
  5. @Inherited//可继承,允许子类继承父类的注解
  6. @Retention(RetentionPolicy.RUNTIME)//注解保留在的位置
  7. public @interface StudentAnnotation {
  8. String name();
  9. int num();
  10. }

二、创建一个对象类

  1. @StudentAnnotation(name = "我是类", num =123)
  2. public class Student extends Thread implements Runnable,Callable{
  3. @StudentAnnotation(name = "我是成员变量", num =121)
  4. private String stuName;
  5. private int age;
  6. private String stuNumb;
  7. @StudentAnnotation(name = "我是带参构造函数", num =121)
  8. public Student(String stuName, int age, String stuNumb) {
  9. this.stuName = stuName;
  10. this.age = age;
  11. this.stuNumb = stuNumb;
  12. }
  13. @StudentAnnotation(name = "我是无参构造函数", num =126)
  14. public Student() {
  15. }
  16. @StudentAnnotation(name = "我是方法showInf", num =122)
  17. public String showInf(){
  18. return "姓名是:"+stuName+",年龄是:"+age+",学号是:"+stuNumb;
  19. }
  20. @StudentAnnotation(name = "我是方法test", num =122)
  21. private void test(){
  22. System.out.println("我是私有方法!test()");
  23. }
  24. public String getStuName() {
  25. return stuName;
  26. }
  27. public void setStuName(String stuName) {
  28. this.stuName = stuName;
  29. }
  30. public int getAge() {
  31. return age;
  32. }
  33. public void setAge(int age) {
  34. this.age = age;
  35. }
  36. public String getStuNumb() {
  37. return stuNumb;
  38. }
  39. public void setStuNumb(String stuNumb) {
  40. this.stuNumb = stuNumb;
  41. }
  42. @Override
  43. public void run() {
  44. // TODO Auto-generated method stub
  45. }
  46. @Override
  47. public Object call() throws Exception {
  48. // TODO Auto-generated method stub
  49. return null;
  50. }
  51. }

三、创建一个测试类,通过反射获取类的信息及属性,方法,构造函数,注解

  1. public class TestCase {
  2. public static void main(String[] args) throws Exception {
  3. TestCase tc=new TestCase();
  4. //三种获得类名的方式
  5. Class cla1=Class.forName("ldl.fanshe619.Student");
  6. Class cla2=Student.class;
  7. Class cla3=new Student().getClass();
  8. System.out.println("类名是:"+cla1);
  9. tc.getSuperClassOrInterface(cla1);
  10. System.out.println("\n--------------------------");
  11. tc.getClassAndModifies(cla1);
  12. System.out.println("--------------------------");
  13. tc.getFields(cla1);
  14. System.out.println("--------------------------");
  15. tc.getMethods(cla1);
  16. System.out.println("--------------------------");
  17. tc.getConstructors(cla1);
  18. System.out.println("--------------------------");
  19. tc.getAnnotation(cla1);
  20. }
  21. //1.获取类的父类和实现的接口
  22. public void getSuperClassOrInterface(Class cla) throws Exception{
  23. String supname=cla.getSuperclass().getName();
  24. System.out.println("继承的父类是:"+supname);
  25. Class[] c1=cla.getInterfaces();
  26. System.out.print("实现的接口有:");
  27. for(Class ca:c1){
  28. System.out.print(ca+",");
  29. }
  30. }
  31. //2.获取类名和访问修饰符
  32. public void getClassAndModifies(Class cla){
  33. //获取类的访问修饰符
  34. int a=cla.getModifiers();
  35. Modifier.toString(a);
  36. System.out.println("类的修饰符是:"+Modifier.toString(a));
  37. }
  38. //3.获取所有成员变量
  39. public void getFields(Class cla) throws Exception{
  40. //获得所有变量的信息
  41. Field[] f=cla.getDeclaredFields();
  42. System.out.println("所有成员变量:");
  43. for(Field fe:f){
  44. System.out.println(Modifier.toString(fe.getModifiers())+" "+fe.getType().getSimpleName()+" "+fe.getName());
  45. }
  46. //获取单个变量的信息
  47. Field fe=cla.getDeclaredField("stuName");
  48. //System.out.println(fe);
  49. //创建Class对象
  50. Object obj=cla.newInstance();
  51. //屏蔽变量的私有特性,并赋值
  52. fe.setAccessible(true);
  53. //没有屏蔽私有属性的变量会赋值失败
  54. fe.set(obj, "张三");
  55. Student st=(Student) obj;
  56. System.out.println("学生名为:"+st.getStuName());
  57. }
  58. //4.获取所有成员方法
  59. public void getMethods(Class cla) throws Exception{
  60. //获取自己类中的方法(所有的公共方法和私有方法)
  61. Method[] me=cla.getDeclaredMethods();
  62. //获取自己类中和所有父类中的所有公共方法
  63. Method[] me2=cla.getMethods();
  64. System.out.println("所有成员方法:");
  65. for(Method meth:me){
  66. System.out.println(Modifier.toString(meth.getModifiers())+" "+meth.getReturnType().getSimpleName()+" "+
  67. meth.getName()+"()"+"{}");
  68. }
  69. //获取test方法
  70. Method mth=cla.getDeclaredMethod("test");
  71. //屏蔽方法的私有属性
  72. mth.setAccessible(true);
  73. //创建对象
  74. Object obj=cla.newInstance();
  75. //实现对test方法的调用
  76. mth.invoke(obj);
  77. }
  78. //5.获取构造函数
  79. public void getConstructors(Class cla) throws Exception{
  80. //获取所有构造函数
  81. Constructor[] con=cla.getConstructors();
  82. for(Constructor cons:con){
  83. System.out.println(cons);
  84. }
  85. //获取定义参数的构造函数
  86. Constructor constr=cla.getConstructor(String.class,int.class,String.class);
  87. Object obj=constr.newInstance("王庆",18,"12345");
  88. Student stu=(Student) obj;
  89. System.out.println(stu.showInf());
  90. }
  91. //6.获取注解
  92. public void getAnnotation(Class cla) throws Exception{
  93. StudentAnnotation stu1=(StudentAnnotation) cla.getAnnotation(StudentAnnotation.class);
  94. System.out.println("类的注解是:"+stu1);
  95. StudentAnnotation stu2=cla.getDeclaredField("stuName").getAnnotation(StudentAnnotation.class);
  96. System.out.println("成员变量的注解是:"+stu2);
  97. StudentAnnotation stu3=cla.getDeclaredMethod("test").getAnnotation(StudentAnnotation.class);
  98. System.out.println("方法的注解是:"+stu3);
  99. StudentAnnotation stu4=(StudentAnnotation)cla.getConstructor().getAnnotation(StudentAnnotation.class);
  100. System.out.println("构造函数的注解是:"+stu4);
  101. }
  102. }

转载于:https://www.cnblogs.com/TFE-HardView/p/11052392.html

发表评论

表情:
评论列表 (有 0 条评论,338人围观)

还没有评论,来说两句吧...

相关阅读

    相关 反射注解

    目录 一、反射——框架设计的灵魂 二、反射获取字节码Class对象的三种方式 三、Class对象的功能概述 四、注解 4.1 JDK中预定义的注解 1.限定父类重

    相关 Java 4注解

    @Tatget 范围(在类上,方法上,还是字段上生效),表示可以用在那些地方 @Retention:定义什么时候生效,有三重,Source,Class, RunTime,一般

    相关 反射注解

    反射 反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性。 反射的作用: Java反射机制提供了以下的功能 在运行时获取类的修饰符,包名,类名,实