注解与反射
前言
在B站跟着狂神学习注解与反射的一些笔记,后期若有补充会更新该博文,加油!
什么是注解?
注解
Annotation是JDK5开始引入的技术
Annotation作用:
- 不适程序本身,可以对程序作出解释
- 可以被其他程序读取,例如编译器
Annotation的格式:
- 注解是以“@注解名”在代码中存在,还可以添加参数值,例如@SuppressWarning(value=“unchecked” ).
Annotation在哪儿使用?
- 可以在package、class、method、field等,相当于起辅助功能,我们可以通过反射机制编程实现对这些元数据的访问
内置注解
@override:定义在java.lang.Override中,该注解用于修辞方法,表示一个方法声明重写超类中的另一个方法声明
@Deprecated:定义在java.lang.Deprecated中,可以用于修饰类、方法、属性、表示不支持程序员使用这种元素,因为有更好的选择。
@SuppressWarnings:定义在java.lang.SuppreWarning中,用来抑制编译时所产生的警告信息。该注解需要添加参数
- @SuppresWarnings(“all”)
- @SuppresWarnings(“unchecked”)
- @SuppresWarnings(value={“unchecked”,“deprecation”})
- .。。
元注解
元注解的作用就是负责注解其他注解,java中定义了四个标准的meta-annotation类型,他们被用来提供对其他annotion的类型作说明。
这些类型在java.lang.annotation中:
- @Target:用于描述注解的使用范围,例如:类、方法
- @Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期,一般在Runtime中
- @Document:说明该注解将被包含在javadoc中
- @Inherited:说明子类可以继承父类中的该注 解
package com.annotation.Demo;
import com.sun.istack.internal.Interned;
import java.lang.annotation.*;
/**
* 元注解,自定义注解
*/
public class AnnotationDemo1 {
// 注解可以显示赋值,没有默认值,我们就必须给注解赋值
// 例如下面的annotation2中
// 不赋值就会报红
@annotation2(age = 22)
public void test2() {
}
// 注解中有默认值,不赋值也不影响程序运行编译
@annotation3(age = 11)
public void test3() {
}
//当只有一个参数的时候可以直接用value来代替,只能用value不能用其他名字代替
@annotation1(value = "11", age = 11,cource = 11.1)
public void test() {
}
@annotation
public void test4(){
}
}
@Target({
ElementType.TYPE, ElementType.METHOD})
@interface annotation2 {
int age();
}
//注解的参数:can'shu'lei'can'shu'lei'xt({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE, ElementType.METHOD})
@interface annotation1 {
String value();
int age();
double cource();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE, ElementType.METHOD})
@interface annotation3 {
// String name() default "小明"; 默认值在括号后面加上 default 再加默认值
String name() default "小红";
int age();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE, ElementType.METHOD})
@interface annotation{
//默认值为"" 0
String name() default "";
int age() default 0;
}
分析:
- 当@interface 自定义注解时,自动继承了java.lang.annotation.Annotation接口
- @interface用来声明一个注解,格式:public @interface 注解名{ 自定义内容}
- 每一个方法实际上就是声明了一个配置参数
- 方法的名称就是参数的名称
- 返回值值类型就是参数的类型(返回值只能是基本类型Class、String、enum等)
- 可以通过default来声明参数的默认值
- 当只有一个参数成员的时候,一般参数名为value
- 注解元素必须要有值,我们自定义注解元素时,经常使用空字符串,0作为默认值
反射
反射机制
java Reflection
- Reflection 反射:是java被视为准动态语言的关键,反射机制郧西程序在执行期间借助于Reflection API取得任何类的内部信息,并且能直接操作任意对象的内部属性及方法
Class c=Class.forName("Java.lang.String")
- 当类加载完后,在堆内存的方法区中就会产生了一个Class类型的对象,一个类只有一个Class对象,这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一潭清澈如镜的湖水,透过湖面我们可以看到类的内部结构,所以我们称之为”反射“。
用游戏中外挂来理解就是:在游戏进行中,启动外挂,就是在运行的过程中创建类的对象。
正常方式:需要引入“包类”名称>>>通过new方法来实例化>>>取得实例化对象
反射方式:实例化对象>>>getClass()>>>得到完整的“包类”名称
举个栗子:
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射
Class c1 = Class.forName("com.reflection.Demo.Demo1");
System.out.println(c1);
// 正常方式
User user = new User();
user.setAge(11);
user.setCource(99.00);
user.setId(001);
user.setName("杜某人");
System.out.println(user.toString());
}
}
//实体类entity 、pojo
class User {
private String name;
private int age;
private double cource;
private int id;
// 无参构造
public User() {
}
// 有参构造
public User(String name, int age, double cource, int id) {
this.name = name;
this.age = age;
this.cource = cource;
this.id = id;
}
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;
}
public double getCource() {
return cource;
}
public void setCource(double cource) {
this.cource = cource;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//方便测试
@Override
public String toString() {
return "User{" +