提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
概念
说明程序的。 给计算机看
定义
注解(Annotation)也叫元数据,一种代码级别的说明。JDK1.5之后引入的特性,与类、接口、枚举在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
概念描述
JDK1.5之后的新特性
说明程序的
使用注释: @注解名称
作用分类
1.编写文档: 通过代码里标识的元数据生成文档 【生成文档doc文档】
—javadoc命令 使.java生成文档
2.代码分析: 通过代码里标识的元数据对代码进行分析 【使用反射】
3.编译检查: 通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
JDK中预定义的一些注解
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
@Override // 检测被注解标注的方法是否是继承自父类(接口)
@Deprecated // 被该注解注释的内容 表示已过时
@SuppressWarnings // 压制警告
自定义注解
格式:
-----元注解
public @interface 注解名称{
属性列表
}
// 本质上是一个接口 默认继承了Annotation接口
// 属性: 接口中可以定义的成员方法 就是接口中的抽象方法
/*
要求: 1. 属性的返回值类型 有下列取值 其他都不行
基本数据类型
String
枚举
注解
以上类型的数组
2. 定义了属性 需要给属性赋值
1. 如果定义属性时 使用default关键字给属性默认初始化值,则使用注解时,可 以不进行属性的赋值。
2. 如果只有一个属性需要赋值,并且属性的名称是value 则value可以省略, 直接定义值即可
3. 数组赋值时,值使用{}包裹。 如果数组中只有一个值,则{}省略
元注解 : 用于描述注解的注解
@Target: 描述注解能够作用的位置
Type:可以作用于类上
METHOD: 可以作用于方法上
FIELD: 可以作用于成员变量上
@Retention: 描述注解被保留的阶段
@Retention(RetentionPolicy.RUNTIME) 当前被描述的注解 会保留到class字节中,并被JVM读取到
@Oocumented: 描述注解是否被抽取到api文档中
@Inherited: 描述注解是否被子类继承
在程序使用注解 : 获取注解中定义的属性值
1. 获取注解定义的位置的对象 (class, Method, Field)
2. 获取指定的注解
getAnnotation(Class)
3. 调用注解中的抽象方法获取配置的属性值
*/
public interface MyAnno extends java.lang.annotation.Annotation{}
// 等于
public @interface MyAnno{
// public abstract String show(); // 接口中方法默认就是 public abstract
int age();
String name() default "张三"; // 默认值
@interface anno2;
}
public @interface MyAnno2{
}
@Target(value={ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) // 表示MyAnno3注解智能作用于类上 方法上 属性上
@Retention(RetentionPolicy.RUNTIME)
@Oocumented
@Inherited 是否能被描述的类的子类继承
public @interface MyAnno3{
}
@MyAnno(age = 12, name = "张三", anno2 = @MyAnno2)
@MyAnno3
public class Worker{
@MyAnno3
public String name = "aaa";
@MyAnno3
public void show(){
}
}
// 通过@Inherited 可以让teacher类使用 @MyAnno3
public class Teacher extends Worker{
}
在程序使用(解析)注解
获取注解的值
/*\
描述需要执行的类名 和方法名
*/
@Target({ElementType.TYPE}) // 使用在类上
@Retention(RetentionPolicy.RUNTIME) // 实在在运行阶段
public @interface Pro {
String className();
String methodName();
}
/*
系统中默认创建了 Pro的实现类 ProImpl
*/
public class Demo1{
public void show(){
System.out.println("demo1...show")
}
}
public class Demo2{
public void show(){
System.out.println("demo2...show")
}
}
@Pro(className = "cn.itcast.annotation.Demo1", methodName= "show")
public class ReflectTest{
public static void main(String[] arg) throws Exception {
/*
前提 不能改变该类的任何代码 可以创建任意类的对象 可以执行任意方法
*/
// 解析注解
// 1. 获取该类的字节码文件对象
Class<ReflectTest> reflectTestClass = ReflectTest.class;
// 2. 获取上边的注解对象
Pro an = reflectTestClass.getAnnotation(Pro.class);
// 3. 调用注解对象中定义的抽象方法 获取返回值
String className = an.className();
// 反射写法
// 1. 加载类到内存
Class cls = Class.forName(className);
// 2. 创建对象
Object obj = cls.newInstance();
// 3. 获取方法对象
Method method = cls.getMethod(methodName);
// 执行方法
method.invoke(obj);
}
}
实例
public class Calculator{
// 加法
@Check
public void add(){
System.out.println("1 + 0 =" + (1 + 0));
}
// 减法
@Check
public void sub(){
System.out.println("1 - 0 =" + (1 - 0));
}
// 乘法
@Check
public void mul(){
System.out.println("1 * 0 =" + (1 * 0));
}
// 除法
@Check
public void div(){
System.out.println("1 / 0 =" + (1 / 0));
}
public void show(){
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check{
}
public static void main(String[] args){
// 1. 创建计算器对象
Calulator c = new Calculator();
// 2. 获取字节码文件对象
Class cls = c.getClass();
// 3. 获取所有方法
Method[] methods = cls.getMethods();
int number = 0; // 出现异常的次数
BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
for(Method method : methods){
// 4. 判断方法上是否有Check注解
if(method.isAnnotationPresent(Check.class)){
// 5. 有, 执行
try {
method.invoke(c);
} catch (Exception e){
// 6. 捕获异常
number ++;
bw.writer( method.getName() + "xxx方法异常了");
bw.newLine();
bw.writer( "异常的名称:" + e.getCause().getClass().getSimpleName());
bw.newLine();
bw.writer( "异常的原因:" + e.getCause().getMessage());
bw.newLine();
bw.writer( "-----------------------");
}
}
bw.write("本次出现"+ num + " 次异常");
bw.flush();
bw.close();
}
}
小结
1.以后大多数时间 使用注解 而不是自定义注解
2.注解给谁用?
1. 编译器
2. 给解析程序用
3. 注解就是一个标签