Java复习第12天---12.4---基础加强---注解

Java复习第12天---12.4---基础加强---注解

目录




内容

1、概述

  注解与注释的区别。

  • 注解:说明程序的,给计算机看的

  • 注释:用文字描述程序的,给程序员看的

  • 定义:注解(Annotation),也叫元数据,一种代码级别的说明。它是JDk1.5及之后版本引入的特殊。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明、注释。

  • 作用分类:

    1. 编写文档:通过代码里面标识的注解生成文档(生成doc文档)
    2. 代码分析:通过代码里标识的注解对代码进行分析(通过反射)
    3. 便宜检查:通过代码里标识的注解让编译器能实现基本的编译检查(Override)

1.1、Javadoc文档

  • 示例1.1-1:

      package annotation;
    
      /**
       * 注解Javadoc演示
       * @author gaogzhen
       * @since 1.5
       * @version 1.0
       */
      public class TestAnnotationDoc {
    
      	/**
      	 * 计算2个整数相加
      	 * @param a 整数
      	 * @param b 整数
      	 * @return 整数-2数相加的和
      	 */
      	public int add(int a, int b) {
      		return a + b;
      	}
      }
      :通过javadoc命令生成javadoc文档
    

2、JDK内置注解

  • @Override:检测被该注解标注的方法是否继承自父类(接口)

  • @Deprecated:被该注解标注的方法,表示已经过时,有其他更好的替代方法

  • @SuppressWarnings:表示在注释元素(以及注释元素中包含的所有程序元素)中应该抑制命名的编译器警告

  • 示例2-1:

      package annotation;
    
      public class TestAnno1 {
    
      	@Override
      	public String toString() {
      		return "TestAnno1 [toString()=" + super.toString() + "]";
      	}
    
      	@Deprecated
      	public void method1() {}
    
      	@MyAnno
      	public void method2() {
      		method1();
      	}
      }
    

3、自定义注解

  在自定义注解前看下内置注解的源码:

	/*
	 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
	 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 *
	 */

	package java.lang;

	import java.lang.annotation.*;
	import static java.lang.annotation.ElementType.*;

	/**
	 * A program element annotated @Deprecated is one that programmers
	 * are discouraged from using, typically because it is dangerous,
	 * or because a better alternative exists.  Compilers warn when a
	 * deprecated program element is used or overridden in non-deprecated code.
	 *
	 * @author  Neal Gafter
	 * @since 1.5
	 * @jls 9.6.3.6 @Deprecated
	 */
	@Documented
	@Retention(RetentionPolicy.RUNTIME)
	@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
	public @interface Deprecated {
	}

  由内置注解的源码,看出:

  • 格式

      元注解
      public @interface 注解名{
      	属性列表;
      }
    

  javap命令查看注解

  • 本质:注解本质上是接口,默认继承自Annotation
    • public interface MyAnno extends java.lang.annotation.Annotation

3.1、注解属性

  • 属性:接口中定义的成员方法,即抽象方法

  • 要求:

    1. 属性的返回值类型
      • 基本数据类型
      • String
      • 枚举
      • 注解
      • 以上类型的数组
    2. 定义了属性,在使用时需要给属性赋值
    3. 可以给属性设置默认值
    4. 如果只有1个属性需要赋值,且属性名为value,则使用时可以省略属性名,直接写值即可
  • 示例3.1-1:

      package annotation;
    
      public @interface MyAnno {
      	int show1();
      	String name() default "gaozhen";
      }
    

3.2、元注解

  用于描述注解的注解。常用元注解:

  • @Target:描述注解可以作用的位置

    • ElementType取值
      • TYPE:可以作用于类上
      • METHOD:可以作用于方法上
      • FIELD:可以作用于属性上
  • @Retention:描述注解被保留的阶段

    • @Retention(RententionPolicy.Runtime):被描述的注解会保留到class字节码中,并被JVM读取
  • @Documented:描述注解是否被抽取到API文档

  • @Inherited:描述注解是否被继承到子类

3.3、解析注解

  • 示例3.3-1:用注解实现执行任意对象的任意方法

      package annotation;
    
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
    
      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Pro {
      	String className();
      	String methodName();
      }
      
      package annotation;
    
      public class AnnoDemo1 {
      	public void show() {
      		System.out.println("Anno Demo1");
      	}
      }
      
      package annotation;
    
      import java.lang.reflect.Method;
    
      /**
       * 通过注解实现任意对象任意方法的执行
       * @author Administrator
       *
       */
      @Pro(className="annotation.AnnoDemo1", methodName="show")
      public class TestReflect1 {
      	public static void main(String[] args) throws Exception {
      		// 1、获取类对象
      		Class<TestReflect1> cls = TestReflect1.class;
      		// 2、获取注解对象
      		Pro anno = cls.getAnnotation(Pro.class);
      		// 3、获取注解属性
      		String className = anno.className();
      		String methodName = anno.methodName();
    
      		// 4、反射生成对象执行方法
      		Class<?> c = Class.forName(className);
      		Object obj = c.newInstance();
      		Method method = c.getDeclaredMethod(methodName, null);
      		method.invoke(obj, null);
      	}
      }
      测试结果:
      Anno Demo1
    

4、小案例

  • 定义一个计算器类,设计个简单的测试框架,并记录日志

  • 检测注解@check代码4-1:

      package reflect;
    
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
    
      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.METHOD})
      public @interface Check {
    
      }
    
  • 计算器类代码4-2:

      package reflect;
    
      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() {
      		System.out.println("永无bug...");
      	}
      }
    
  • 测试类框架4-3:

      package reflect;
    
      import java.io.BufferedWriter;
      import java.io.FileWriter;
      import java.io.IOException;
      import java.lang.reflect.Method;
    
      public class TestCalculator {
      	public static void main(String[] args) throws IOException {
      		// 1、定义计算器对象
      		Calculator c = new Calculator();
      		// 2、获取字节码对象
      		Class<Calculator> cls = (Class<Calculator>) c.getClass();
      		// 3、获取所有方法
      		Method[] methods = cls.getMethods();
    
    
      		// 6、捕获异常
      		int count = 0; // 记录异常次数
      		BufferedWriter bw = new BufferedWriter(new FileWriter("calculator.log"));
      		for(Method method: methods) {
      			// 4、获取@check注解的方法
      			if(method.isAnnotationPresent(Check.class)) {
      				// 5、执行@注解的方法
      				// 6、捕获异常
      				try {
      					method.invoke(c, null);
      				} catch (Exception e) {
      					// 7、记录日志
      					count++;
    
      					bw.write(method.getName() + "方法出现异常");
      					bw.newLine();
      					bw.write("异常的名称:" + e.getCause().getClass().getSimpleName());
      					bw.newLine();
      					bw.write("异常的原因:" + e.getCause().getMessage());
      					bw.newLine();
      					bw.write("============");
      				}
      			}
      		}
    
      		bw.newLine();
      		bw.write("本次测试一共出现  " + count + " 次异常");
      		bw.flush();
      		bw.close();
      	}	
      }
      测试结果:calculator.log内容
      div方法出现异常
      异常的名称:ArithmeticException
      异常的原因:/ by zero
      ============
      本次测试一共出现  1 次异常
    

后记

本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785

前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
    后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gaog2zh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值