目录
-
注解的理解
* 概念:针对Java编译器的说明
* 注释:⽤⽂字描述程序的。给程序员看的
* 定义:注解(Annotation),也叫元数据。⼀种代码级别的说明。它是JDK1.5及以后版本引⼊的⼀个特性,与
类、接⼝、枚举是在同⼀个层次。它可以声明在包、类、字段、⽅法、局部变量、⽅法参数等的前⾯,⽤来对这些元素
进⾏说明,注释。
* 概念描述:
* JDK1.5之后的新特性
* 针对Java编译器的说明
* 使⽤注解:@注解名称
实际案例
//使⽤框架的类 @Controller public class UserController extends BaseController{ @Autowired UserService userService; @RequestMapping("/user/toLogin.action") public String toLogin() { return "/login.jsp"; } @RequestMapping("/user/login.action") public String login(User user,Model model,HttpServletRequest request) { Map<String,String> map=new HashMap<String,String>(); map.put("name", user.getName()); map.put("password", user.getPassword()); if(userService.findUserByName(map)) { request.getSession().setAttribute("user","jiang"); return "/admin/index.jsp"; } model.addAttribute("errorMsg", "登录失败!账号或密码错误!"); return "/login.jsp"; } //普通的类 public class Anno { @Override public String toString() { return super.toString(); } }
-
注解作⽤分类:
①编写⽂档:通过代码⾥标识的注解⽣成⽂档【⽣成⽂档doc⽂档】
示例:
/** * 这⾥⼀个注解的类使⽤ * @author tt * @version 1.0 * @since 1.5 */ public class Anno { /** * 这⾥⼀个计算总合的⽅法 * @param a 参数1 * @param b 参数2 * @return 返回值 */ public int addSum(int a, int b) { return a + b; } }
-
doc⽂件⽣成的命令:
-javadoc
②代码分析:跟踪代码依赖性,实现替代配置⽂件功能,⽐较常⻅的是spring 2.5 开始的基于注解配置。
@RequestMapping("/user/login.action") public String login(User user,Model model,HttpServletRequest request) { Map<String,String> map=new HashMap<String,String>(); map.put("name", user.getName()); map.put("password", user.getPassword()); if(userService.findUserByName(map)) { request.getSession().setAttribute("user","jiang"); return "/admin/index.jsp"; } model.addAttribute("errorMsg", "登录失败!账号或密码错误!"); return "/login.jsp"; }
③编译检查:通过代码⾥标识的注解让编译器能够实现基本的编译检查【Override】
//普通的类 public class Anno { @Override public String toString() { return super.toString(); } }
作⽤总结:
①编写⽂档:通过代码⾥标识的注解⽣成⽂档【⽣成⽂档doc⽂档】 ②代码分析:通过代码⾥标识的注解对代码进⾏分析【使⽤反射】 ③编译检查:通过代码⾥标识的注解让编译器能够实现基本的编译检查【Override】
-
JDK中预定义的⼀些注解
* @Override :检测被该注解标注的⽅法是否是继承⾃⽗类(接⼝)的 * @Deprecated:该注解标注的内容,表示已过时 * @SuppressWarnings:压制警告 * ⼀般传递参数all @SuppressWarnings("all")
@Override :检测被该注解标注的⽅法是否是继承⾃⽗类(接⼝)的
//普通的类 public class Anno { @Override public String toString() { return super.toString(); } }
@Deprecated:该注解标注的内容,表示已过时
@SuppressWarnings:压制警告
*⼀般传递参数all @SuppressWarnings("all")
@SuppressWarnings("all")//加类身上代表类中所有的警告忽略 public class Anno2 { @Override public String toString() { return super.toString(); } //第⼀版写的类 /** * 这个版本过期了,建议后期使⽤show2()⽅法 */ @SuppressWarnings("all") //加⽅法身上代表⽅法上的所有警告忽略 @Deprecated public void show1() { //后期发现这个⽅法有些问题 System.out.println("第⼀版⽅法"); } //第⼆版写的类 public void show2() { //改善版的类 System.out.println("第⼆版⽅法"); } }
预定义注解总结:
* @Override :检测被该注解标注的⽅法是否是继承⾃⽗类(接⼝)的 * @Deprecated:该注解标注的内容,表示已过时 * @SuppressWarnings:压制警告 * ⼀般传递参数all @SuppressWarnings("all")
-
自定义注解
格式:
元注解 public @interface 注解名称{ 属性列表; }
参考系统的注解:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Deprecated { } @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
本质:注解本质上就是⼀个接⼝,该接⼝默认继承Annotation接⼝
测试
1.定义注解
package com.zy.annotation; public @interface Ann03 { }
2.反编译后代码
oldyang@xh:~/Desktop/projects/test02/src/com/zy/annotation$ javac Ann03.java oldyang@xh:~/Desktop/projects/test02/src/com/zy/annotation$ javap Ann03 警告: ⼆进制⽂件Ann03包含com.zy.annotation.Ann03 Compiled from "Ann03.java" public interface com.zy.annotation.Ann03 extends java.lang.annotation.Annotation { }
属性:接⼝中的抽象⽅法
要求: 1. 属性的返回值类型有下列取值 * 基本数据类型 * String * 枚举 * 注解 * 以上类型的数组 2. 定义了属性,在使⽤时需要给属性赋值 1. 如果定义属性时,使⽤default关键字给属性默认初始化值,则使⽤注解时,可以不进⾏属性的赋值。 2. 如果只有⼀个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。 3. 数组赋值时,值使⽤{}包裹。如果数组中只有⼀个值,则{}可以省略
元注解:⽤于描述注解的注解
元注解:⽤于描述注解的注解 * @Target:描述注解能够作⽤的位置 * ElementType取值: * TYPE:可以作⽤于类上 * METHOD:可以作⽤于⽅法上 * FIELD:可以作⽤于成员变量上 * @Retention:描述注解被保留的阶段 * Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值: 1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽 略 2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class⽂件中存在,但 JVM将会忽略 3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运⾏时 被JVM或其他使⽤反射机制的代码所读取和使⽤. * @Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码⽂件中,并 被JVM读取到,我们⾃定义的⼀般使⽤这个阶段 * @Documented:描述注解是否被抽取到api⽂档中 * @Inherited:描述注解是否被⼦类继承
示例:
import java.lang.annotation.*; //TYPE:作⽤于类上⾯ @Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Ann04 { }
@Ann04 @Ann03(name = "⼩灰",years = 2022,p = Person.p1,ann01 = @Ann01) public class Test01 { public static void main(String[] args) { Anno2 anno2 = new Anno2(); anno2.show1(); Date date = new Date(); date.getYear(); } @Ann04 public void show() { } @Ann04 int a; }
执⾏的命令:
javadoc *.java -d doc -version -author
效果
在程序使⽤(解析)注解:获取注解中定义的属性值
在程序使⽤(解析)注解:获取注解中定义的属性值 1. 获取注解定义的位置的对象 (Class,Method,Field) 2. 获取指定的注解 * getAnnotation(Class) 3. 调⽤注解中的抽象⽅法获取配置的属性值
-
定义注解类
package com.zy.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author tt */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ConfigInfo { String className();//类名 String methodName();//⽅法名 }
-
定义测试的类
package com.zy.annotation; public class Demo01 { public void show() { System.out.println("这⾥测试打印的信息!"); } public void show2(String info) { System.out.println("这⾥测试打印的信息!"+info); } }
-
定义注解使⽤测试的类
package com.zy.annotation; @ConfigInfo(className = "com.zy.annotation.Demo01",methodName = "show2") public class Test02 { public static void main(String[] args) throws Exception { //1.解析注解 //1.1获取该类的字节码⽂件对象 Class<Test02> aClass = Test02.class; //2.获取上边的注解对象 ConfigInfo annotation = aClass.getAnnotation(ConfigInfo.class); //3.调⽤注解中定义的⽅法,获取返回值 String className = annotation.className(); String methodName = annotation.methodName(); //初始化 Class aClass1 = Class.forName(className); aClass1.getMethod(methodName,String.class).invoke(aClass1.newInstance(),"2020"); } }
-