java注解与反射

张春  金牌会员 | 2023-5-31 01:36:14 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 925|帖子 925|积分 2775

java注解与反射


  • java注解与反射十分重要,是很多框架的底层
注解(Annotataion)


  • 注解的作用:
    1.    1. 不是程序本身,可以对程序作出解释
    2.    1. 可以被其他程序读取
    复制代码
  • 注解的格式:@注释名,如@override表示重写方法,而且有些还可以添加一些参数值,如@SuppressWarnings(value="unchecjed")
  • 注解可以附加在package,class,method,field等上面,相当于添加了额外的辅助信息。可以通过反射机制编程实现对这些元数据的访问
内置注解


  • @Override:重写方法
  • @Deprecated:表示不被鼓励使用或者已废弃已过时
  • @SuppressWarning:用来抑制编译时的警告信息,但是需要添加一个或多个参数:如("all"),("unchecked")等,平时最好还是不要用这个
使用方法:
  1. @Override
  2. public  void run() {
  3. }
复制代码
其他类似。
元注解

<ul>负责注解其他注解
包括(@Target,@Retention,@Documented,@Inherited),分别表示<ol>
描述注解使用范围
需要上面级别保存该注释信息,用于描述注解的生命周期(SOURCE class1 = Class.forName("com.xxx.Teacher");        System.out.println(class1);//        比较两者        System.out.println(aClass==class1);//        方式三:通过类名.class获得        Class teacherClass = Teacher.class;        System.out.println(teacherClass);//        比较        System.out.println(teacherClass==class1);//        方式四:基本数据类型的包装类的type属性        Class type = Integer.TYPE;        System.out.println(type);//        得到父类Class类型        Class superclass = class1.getSuperclass();        System.out.println(superclass);//     补充一下,获得注解和void和Class本身的Class对象        // Override.class        // void.class        //Class.class    }}class Teacher extends  Person{}/*class com.xxx.Teacherclass com.xxx.Teachertrueclass com.xxx.Teachertrueintclass com.xxx.Person[/code]那些类型可以有Class对象?

包括以下:

注意:数组长度即使不一致,只要类型和维度一样,就是同一个Class
Class类的方法

获得类完整结构
  1. //下面只能用到方法上,value的值可以取多个至于那些可以取CTRL+左键点击ElementType类去看,另外可以省略value=
  2. @Target(value = ElementType.METHOD)
  3. //只能存在于源码上。值有那些同上,自己点进去看RetentionPolicy类,一般取RUNTIME
  4. @Retention(value = RetentionPolicy.SOURCE)
  5. //这两个不多说
  6. @Documented
  7. @Inherited
  8. //自定义注解
  9. @interface MyAnnotation{
  10. }
复制代码
操作类结构
  1. //元注解
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Inherited
  4. //自定义注解
  5. @interface MyAnnotation{
  6. //    注解参数:参数类型+参数名(),可以设置默认值,没默认值的话使用时必须传参
  7.     String name() default "";
  8.     int a();
  9.     int c() default 1;
  10. }
  11. //使用
  12. @MyAnnotation(name = "lihua",a = 1)
复制代码
类的加载过程



解释一下符号引用和直接引用:
符号引用你可以理解为要引用的类目前在内存中还没被加载出来,JVM当然不知道它在哪里。所以就用唯一的符号来表示就好像给它赋了一个变量,等到链接的时候类加载器解析地址完成变成直接引用
直接引用就是存储引用类在真实内存中的地址
总而言之还是这张图:

什么时候会发生类的初始化


主动引用比较好理解,下面只演示一下被动引用“
  1. public static void main(String[] args) throws ClassNotFoundException {
  2.     /*1.下面是通过反射获取Class对象的一种方式,参数是文件路径
  3.       2.一个类在内存中只有一个Class类,在多创建几个该类的Class
  4.      也是同一个。
  5.       3一个类被加载后,类的整个结构都会被封装在Class对象中
  6.       4.我们经常用的Object的getClass方法就是返回一个Class对象,也是创建Class对象的一种常用方式
  7.       5.反射在某种情况下可以理解为通过一个对象获得类
  8.      */
  9.     Class<?> aClass = Class.forName("com.xxx.MyThread");
  10.     System.out.println(aClass);
  11. }
  12. //out:class com.xxx.MyThread
复制代码
类加载器


  • 类加载的作用:将class文件字节码内容加载到内存中,并且将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class 对象,作为方法区中类数据的访问入口。简单来说,类加载器的作用就是把类(class)装进内存
  • 类缓存:标准的JavaSE类加载器可以按照要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段数据。不过JVM垃圾回收机制可以回收这些Class对象

类加载器有那些?


java的主要jar包就是rt.jar,引导类加载器就是加载这一类核心jar包
  1. public class Test {
  2.     public static void main(String[] args) throws ClassNotFoundException {
  3.         Teacher teacher = new Teacher();
  4. //        方式一:通过对象
  5.         Class aClass = teacher.getClass();
  6.         System.out.println(aClass);
  7. //        方式二:forname
  8.         Class<?> class1 = Class.forName("com.xxx.Teacher");
  9.         System.out.println(class1);
  10. //        比较两者
  11.         System.out.println(aClass==class1);
  12. //        方式三:通过类名.class获得
  13.         Class<Teacher> teacherClass = Teacher.class;
  14.         System.out.println(teacherClass);
  15. //        比较
  16.         System.out.println(teacherClass==class1);
  17. //        方式四:基本数据类型的包装类的type属性
  18.         Class<Integer> type = Integer.TYPE;
  19.         System.out.println(type);
  20. //        得到父类Class类型
  21.         Class<?> superclass = class1.getSuperclass();
  22.         System.out.println(superclass);
  23. //     补充一下,获得注解和void和Class本身的Class对象
  24.         // Override.class
  25.         // void.class
  26.         //Class.class
  27.     }
  28. }
  29. class Teacher extends  Person{}
  30. /*
  31. class com.xxx.Teacher
  32. class com.xxx.Teacher
  33. true
  34. class com.xxx.Teacher
  35. true
  36. int
  37. class com.xxx.Person
复制代码
反射操作泛型

  1. public class MyThread {
  2.     private  int a;
  3.     public  void run(String a){}
  4.     public int getA() {
  5.         return a;
  6.     }
  7.     public void setA(int a) {
  8.         this.a = a;
  9.     }
  10.     public MyThread(int a) {
  11.         this.a = a;
  12.     }
  13.     public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
  14.         Class c1 = Class.forName("com.xxx.MyThread");
  15.         //获取类名
  16.         System.out.println(c1.getName());
  17.         System.out.println(c1.getSimpleName());
  18. //        获得类属性
  19.         Field[] fields = c1.getFields();//只能找到public属性
  20.         fields = c1.getDeclaredFields();
  21.         for (Field field : fields) {
  22.             System.out.println(field);
  23.         }
  24. //        获得类方法
  25.         System.out.println("-----------------------");
  26.         Method[] methods = c1.getMethods();//包括继承的方法
  27.         methods=c1.getDeclaredMethods();//只包括本类的方法
  28.         for (Method method : methods) {
  29.             System.out.println(method);
  30.         }
  31.         System.out.println("-------------------------------");
  32. //        获得指定方法:没s,两个参数分别是方法名和方法参数类型的Class
  33.         System.out.println(c1.getMethod("run",String.class));
  34. //        获得构造器
  35.         System.out.println("----------------");
  36.         Constructor[] constructors = c1.getConstructors();//获得public构造器
  37.         for (Constructor constructor : constructors) {
  38.             System.out.println(constructor);
  39.         }
  40. //        同理getDeclaredConstructors()获得的所有构造器,
  41.         //获得指定的构造器,参数为构造器参数的Class
  42.         System.out.println("--------------------------");
  43.         Constructor constructor = c1.getConstructor(int.class);
  44.         System.out.println(constructor);
  45.     }
  46. }
  47. /*out:
  48. public void com.xxx.MyThread.run(java.lang.String)
  49. public void com.xxx.MyThread.setA(int)
  50. public int com.xxx.MyThread.getA()
  51. -------------------------------
  52. public void com.xxx.MyThread.run(java.lang.String)
  53. ----------------
  54. public com.xxx.MyThread(int)
  55. --------------------------
  56. public com.xxx.MyThread(int)
复制代码
反射操作注解

ORM->对象关系映射
  1. public class MyThread {
  2.     private  int a;
  3.     public  void run(String a){
  4.         System.out.println(a);
  5.     }
  6.     public int getA() {
  7.         return a;
  8.     }
  9.     public MyThread() {
  10.     }
  11.     public void setA(int a) {
  12.         this.a = a;
  13.     }
  14.     public MyThread(int a) {
  15.         this.a = a;
  16.     }
  17.     public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
  18.         Class<?> aClass = Class.forName("com.xxx.MyThread");
  19. //        构建一个对象:本质是调用无参构造器,其该类必须有无参构造器
  20. //        MyThread myThread = (MyThread)aClass.newInstance();
  21. //        通过构造器创建对象,可以用有参构造函数
  22. //       Constructor constructor= aClass.getDeclaredConstructor(int.class);
  23. //       MyThread myThread1=(MyThread)constructor.newInstance(1);
  24. //       通过反射调用方法
  25. //        通过反射获取一个方法
  26.         MyThread myThread = (MyThread) aClass.newInstance();
  27.         Method setName = aClass.getMethod("run", String.class);
  28. //        invoke:激活,参数:对象名,方法参数
  29.         setName.invoke(myThread,"helloworld");
  30. //        通过反射操作属性
  31.         Field a=aClass.getDeclaredField("a");
  32. //        取消安全检查,否则无法操作私有属性.method,field,consructor都有它,关闭也可以提高反射效率
  33.         a.setAccessible(true);
  34.         a.set(myThread,5);
  35.         System.out.println(myThread.a);
  36.     }
  37.    
  38.    /*out:
  39.    helloworld
  40.         5
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表