注解与反射

内置注解与元注解

Java的5个内置注解(基本注解):

@Deprecated 过时

用于过时的类、方法、成员变量等

@Override

覆盖父类方法

@SuppressWarning

阻止警告

@FunctionaInterface

指定接口必须为函数式接口(有且只有一个抽象方法的接口)

@SafeVarargs

一直"堆污染警告":只能用于标记构造方法或用static或final声明的方法,声明构造函数和方法的主体不会对其varargs参数执行潜在的不安全的操作,用来抑制某些对模糊类型的可变参数报的unchecked异常。

4种元注解: 能注解到注解上的注解,能用在其他注解上的注解。

@Retention 保留期,能设定注解的存活时间

@Documented

将注解中的元素包含到Javadoc中:这个注解只是用来标注生成javadoc的时候是否会被记录。

@Target

限定注解能运用的地方

@Inherited

标明注解是能被继承的,例如B继承了A,A添加了注解,那么B也会继承同样的注解

自定义注解

语法: public @interface xxx{}

使用:@xxx

注解只有成员变量,没有方法

public @interface Xxx{
  int a();
  char b();    
}//使用@Xxx(a=1,b="b")

若属性只有value,使用时可采用简写:

public @interface Xxx{
  String value();  
}
@Xxx("11")

反射

Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。**这也是java语言可以被视为准动态语言的原因。**动态语言:允许改变程序结构或变量类型。

获得反射对象

Class.forName();
student.getClass();
Student.class;

类加载的过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7SbqLool-1661325874487)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211114211347634.png)]

类加载的过程中,首于是先在内存中的方法区中加载类中的静态变量,静态方法,常量池等,然后再在堆中生成对应的class类对象。主线程开始运行时,main方法进栈,然后在堆中创建A类对象,A类对象在对应的类中拿到类中所有的信息,于是执行方法体,对a赋值。

百度详解:

JVM把class文件加载到内存,并对数据进行校验、准备、解析、初始化,最终形成JVM可以直接使用的Java类型的过程。

img

1.加载

将class字节码文件加载到内存中,并将这些数据转换成方法区中的运行时数据(静态变量、静态代码块、常量池等),在堆中生成一个Class类对象代表这个类(反射原理),作为方法区类数据的访问入口。

2、链接

将Java类的二进制代码合并到JVM的运行状态之中。
• 验证
确保加载的类信息符合JVM规范,没有安全方面的问题。
• 准备
正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。注意此时的设置初始值为默认值,具体赋值在初始化阶段完成。
• 解析
虚拟机常量池内的符号引用替换为直接引用(地址引用)的过程。

3、初始化

初始化阶段是执行类构造器()方法的过程。类构造器()方法是由编译器自动收集类中的所有类变量的赋值动作和**静态语句块(static块)**中的语句合并产生的。

  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化、则需要先初始化其父类。
  • 虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步。

类加载机制:双亲委派机制。在tomcat服务器类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AItWoogd-1661325874489)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211114215530896.png)]

获取类的运行时结构

//只获得public属性
Field[] field = aClass.getFields();
//获得全部属性
Field[] declaredFields = aClass.getDeclaredFields();
//获得本类及其父类的全部public方法
Method[] methods = aClass.getMethods();
//获得本类中的所有方法
Method[] declaredMethods = aClass.getDeclaredMethods();

动态创建对象执行方法

通过反射创建对象

//构造一个对象,本质上是调用了类的无参构造器
Object o = aClass.newInstance();

也可以通过反射来操作类的属性和方法。

通过反射拿到方法之后,再通过invoke()方法执行。

注意:当遇到权限问题时,可通过 属性名。setAcessible()方法来设置属性可访问。

通过反射获得注解

getAnnotations();

getAnnotation(arg[]);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6N4sXkgI-1661325874489)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211115164948887.png)]
当遇到权限问题时,可通过 属性名。setAcessible()方法来设置属性可访问。

通过反射获得注解

getAnnotations();

getAnnotation(arg[]);

[外链图片转存中…(img-6N4sXkgI-1661325874489)]

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...