注解(1)

实际案例 :
* 概念:针对 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";

} 2. 注解作⽤分类:
①编写⽂档:通过代码⾥标识的注解⽣成⽂档【⽣成⽂档 doc ⽂档】
示例 :
doc ⽂件⽣成的命令 :
②代码分析:跟踪代码依赖性,实现替代配置⽂件功能 , ⽐较常⻅的是 spring 2.5 开始的基于注解配置。
// 普通的类
public class Anno {
@Override
public String toString () {
return super . toString ();
}
}
/**
* 这⾥⼀个注解的类使⽤
* @author ⼩灰
* @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 ;
}
}
- javadoc ③编译检查:通过代码⾥标识的注解让编译器能够实现基本的编译检查【 Override
作⽤总结 :
3.JDK 中预定义的⼀些注解
@Override :检测被该注解标注的⽅法是否是继承⾃⽗类 ( 接⼝ )
@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 ⽂档】
②代码分析:通过代码⾥标识的注解对代码进⾏分析【使⽤反射】
③编译检查:通过代码⾥标识的注解让编译器能够实现基本的编译检查【 Override
* @Override :检测被该注解标注的⽅法是否是继承⾃⽗类 ( 接⼝ )
* @Deprecated :该注解标注的内容,表示已过时
* @SuppressWarnings :压制警告
* ⼀般传递参数 all @SuppressWarnings ( "all" )
// 普通的类
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 ( " 第⼆版⽅法 " );
}
} 预定义注解总结 :
4. ⾃定义注解
格式 :
参考系统的注解 :
本质:注解本质上就是⼀个接⼝,该接⼝默认继承 Annotation 接⼝
测试
1. 定义注解
2. 反编译后代码
* @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 ();
}
package com . zy . annotation ;
public @interface Ann03 {
} 属性:接⼝中的抽象⽅法
元注解:⽤于描述注解的注解
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. 定义注解类
在程序使⽤ ( 解析 ) 注解:获取注解中定义的属性值
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 ⼩灰
*/
@Retention ( RetentionPolicy . RUNTIME )
@Target ( ElementType . TYPE )
public @interface ConfigInfo {
String className (); // 类名
String methodName (); // ⽅法名
} 2. 定义测试的类
3. 定义注解使⽤测试的类
5. 案例:简单的测试框架
1. 被测试的类
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" );
}
}
package com . zy . annotation2 ;
// 计算器的类
public class Calculator {
// 定义⼀个⽅法
// 加法 2. 注解类
@Check
public void add () {
int a = 1 / 0 ;
System . out . println ( " 这⾥加法 " );
}
// 减法
@Check
public void sub () {
int a = 1 / 0 ;
System . out . println ( " 这⾥减法 " );
}
// 乘法
@Check
public void mul () {
String a = null ;
a . getBytes ();
System . out . println ( " 这⾥乘法 " );
}
// 除法
@Check
public void div () {
System . out . println ( " 这⾥除法 " );
}
}
package com . zy . annotation2 ;
import javax . swing . * ;
import java . lang . annotation . ElementType ;
import java . lang . annotation . Retention ;
import java . lang . annotation . RetentionPolicy ;
import java . lang . annotation . Target ;
/** ⽤来检测⽅法是否有异常
* @author ⼩类
*
*/
@Retention ( RetentionPolicy . RUNTIME )
@Target ( ElementType . METHOD )
public @interface Check {
} 3. 测试框架类
package com . zy . annotation2 ;
import java . io . BufferedWriter ;
import java . io . FileWriter ;
import java . io . IOException ;
import java . lang . reflect . InvocationTargetException ;
import java . lang . reflect . Method ;
import java . util . Calendar ;
/**
* 做⼀个简单的测试的框架
* //1. 创建测试的类
* //2. 得到字节码
* //3. 获取所有的⽅法
* //4. 判断是否⽅法上有 Check 注解
* //5. 有就执⾏⽅法
* //6. 捕获异常
* main ⽅法执⾏的时候 , 会⾃动去检测所有的⽅法 ( 加了 @check 的⽅法 ), 判断是否有异常 , 并把异常记录到⽂件中
*/
public class TestMethod {
public static void main ( String [] args ) throws Exception {
// 定义异常计数
int number = 0 ;
// 定义异常的⽂件流
BufferedWriter bufferedWriter = new BufferedWriter ( new FileWriter ( "bug.txt" ,
false ));
//1. 创建测试的类
Calculator calculator = new Calculator ();
//2. 得到字节码
Class aClass = calculator . getClass ();
//3. 获取所有的⽅法
Method [] methods = aClass . getMethods ();
for ( Method method : methods ) {
//4. 判断是否⽅法上有 Check 注释
if ( method . isAnnotationPresent ( Check . class )) {
try {
//5. 有就执⾏⽅法
//6. 捕获异常
method . invoke ( calculator );
} catch ( Exception e ) {
e . printStackTrace ();
number ++ ; // 异常加 1
bufferedWriter . write ( method . getName () + " ⽅法出异常了 !" );
bufferedWriter . newLine ();
bufferedWriter . write ( " 异常的名称 :" + e . getCause (). getClass ());
bufferedWriter . newLine (); bufferedWriter . write ( " 异常的原因 :" + e . getCause (). getMessage ());
bufferedWriter . newLine ();
bufferedWriter . write ( "----------------------------" );
bufferedWriter . newLine ();
}
}
}
bufferedWriter . write ( " 本次⼀共出现 " + number + " 次异常 !" );
bufferedWriter . newLine ();
bufferedWriter . flush ();
bufferedWriter . close ();
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值