Annotaion 注解 详解案例

举报
牧小农 发表于 2022/05/26 00:51:21 2022/05/26
【摘要】 1、注解入门 2、内置注解 3、自定义注解、元注解 4、小案例(使用反射读取注解的信息,模拟处理注解信息的流程) 1、注解入门 Annotation是从JDK5.0开始引入的新技术 Annotation的作用: 不是程序本身,可以对程序作出解释(其实这一点,和注释很像)可以被其他程序(比如:编译器)读取...

1、注解入门

2、内置注解

3、自定义注解、元注解

4、小案例(使用反射读取注解的信息,模拟处理注解信息的流程)


1、注解入门


Annotation是从JDK5.0开始引入的新技术

Annotation的作用:

不是程序本身,可以对程序作出解释(其实这一点,和注释很像)可以被其他程序(比如:编译器)读取(注解信息处理流程,是注解和注释的重大区别,如果没有注解信息处理流程,则注解毫无意义)

Annotation的格式:

注解是以”@注释名”在代码中存在的,还可以添加一些参数值,例如SuppressWarnings(value=”all”)

Annotation在哪里使用

可以附加在package、class、mehod、field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制实现对这些元数据的访问


2、内置注解


@Override

定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明


  
  1. /*
  2. * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
  3. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. package java.lang;
  6. import java.lang.annotation.*;
  7. /**
  8. * 表示方法声明的目的是重写
  9. * 在父类方法声明。如果一个方法被注释
  10. * 此注释类型编译器将生成一个错误
  11. * 除非下列情况中至少有下列情况之一:
  12. *
  13. * <ul><li>
  14. * 该方法是否重写或实现在一个声明中声明的方法
  15. * 超类.
  16. * </li><li>
  17. * 该方法具有一个与该等效的签名
  18. * 任何公开声明的方法在 {@linkplain Object}.
  19. * </li></ul>
  20. *
  21. * @author Peter von der Ahé
  22. * @author Joshua Bloch
  23. * @jls 9.6.1.4 Override
  24. * @since 1.5
  25. */
  26. @Target(ElementType.METHOD)
  27. @Retention(RetentionPolicy.SOURCE)
  28. public @interface Override {
  29. }

@Depercated

定义在java.lang.Deprecated中,此注释用户修辞方法、属性、类表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择



  
  1. /*
  2. * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  3. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. package java.lang;
  6. import java.lang.annotation.*;
  7. import static java.lang.annotation.ElementType.*;
  8. /**
  9. * @Deprecated<strong> </strong>程序元素的注释 是一个程序员使用
  10. * 不要使用,通常是因为它是危险的,
  11. * 或因为一个更好的选择存在。编译器发出警告
  12. * 过时的程序元素的使用或重写非过时的代码。
  13. *
  14. * @author Neal Gafter
  15. * @since 1.5
  16. */
  17. @Documented
  18. @Retention(RetentionPolicy.RUNTIME)
  19. @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
  20. public @interface Deprecated {
  21. }

@SuppressWarnings

定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息


  
  1. /*
  2.  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  3.  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4.  */
  5. package java.lang;
  6. import java.lang.annotation.*;
  7. import static java.lang.annotation.ElementType.*;
  8. /**
  9.  * 指示将被命名为编译器警告
  10.  * 注释的元素(以及在注释中包含的所有程序元素中的
  11.  * 元素)。请注意,在一个给定的元素中被抑制的一组警告
  12.  * 警告抑制所有包含元素的一个超集。对于
  13.  * 例如,如果您注释一个类,以抑制一个警告和注释
  14.  * 方法来抑制另一个,这两个警告将被抑制的方法。
  15.  *
  16.  * <p>作为一种风格,程序员应该经常使用这个注释
  17.  * 在最深层嵌套元素,它是有效的。如果你想
  18.  * 在特定的方法中抑制警告,您应该批注
  19.  * 方法,而不是其类。
  20.  *
  21.  * @since 1.5
  22.  * @author Josh Bloch
  23.  */
  24. @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
  25. @Retention(RetentionPolicy.SOURCE)
  26. public @interface SuppressWarnings {
  27.     /**
  28.      * 在编译器中被抑制的警告集
  29.      * 注释元素。允许重复名称。第二
  30.      * 连续出现的名称被忽略。在场的
  31.      * 无法识别的警告名称是不一个错误:编译器必须
  32.      * 忽略任何警告名称,他们不承认。然而,他们是,
  33.      * 如果一个注释包含一个未被识别的,自由发出警告
  34.      * 警告名称。
  35.      *
  36.      * <p>编译器供应商应该记录他们支持的警告名称
  37.      * 与此注释类型一起使用。鼓励他们合作
  38.      * 确保在多个编译器上工作相同的名称。
  39.      */
  40.     String[] value();
  41. }


使用这些内置注解


  
  1. package com.lyy.test.annotion;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. import java.util.List;
  5. @SuppressWarnings("all")
  6. public class Demo1 /*extends Object*/{
  7. @Override
  8. public String toString(){
  9. return "";
  10. }
  11. @Deprecated
  12. public static void <del>testoo1</del>(){
  13. System.out.println("test.001");
  14. }
  15. public static void test002(){
  16. List list = new ArrayList<>();
  17. }
  18. public static void main(String[] args) {
  19. Date d = new Date();
  20. <del>testoo1</del>();
  21. }
  22. }



@SuppressWanings

定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了


 参数                                                           说明

 Deprecation            使用了过时的类或方法的警告

 Unchecked    执行了为检查的转换时的警告,如使用集合时未指定泛型

 Fallthrouqh              当在switch语句使用时发生case穿透

 Path                         在类路径、源文件路径等中有不存在路径的警告

 Serial          当在可序列化的类上缺少serialVersionUID定义时的警告

 Finally        任何filally子句不能完成时的警告

 All        关于以上所有情况的警告



3、自定义注解和元注解

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

要点:

@interface用来声明一个注解

格式为:public @interface 注解名(定义体)

其中的每一个方法实际上是声名了一个配置参数

方法的名称就是参数的名称

返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)

可以通过default来声明参数的默认值

如果只有一个参数成员,一般参数名为value



  
  1. package com.lyy.test.annotion;
  2. @SxtMyAnnotation
  3. public class Demo2 {
  4. @SxtMyAnnotation(age=19,studentName="泡泡", id=1001,schools={"北京大学","孝感学院"})
  5. public void test(){
  6. }
  7. @SxtAnnotation2("1")
  8. public void test2(){
  9. }
  10. }



  
  1. package com.lyy.test.annotion;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Target(value={ElementType.METHOD,ElementType.TYPE})
  7. @Retention(RetentionPolicy.RUNTIME)
  8. public @interface SxtMyAnnotation {
  9. String studentName() default "";
  10. int age() default 18;
  11. int id() default -1;
  12. String[] schools() default {"清华大学","湖北学院"};
  13. }



  
  1. package com.lyy.test.annotion;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Target(value={ElementType.METHOD,ElementType.TYPE})
  7. @Retention(RetentionPolicy.RUNTIME)
  8. public @interface SxtAnnotation2 {
  9. String value();
  10. }



最常用到的就是@Target和@Retenion两个元注解







4、小案例

使用反射读取注解的信息,模拟处理注解信息的流程



  
  1. <span style="font-size:14px;">package com.lyy.test.annotion;
  2. import java.lang.annotation.Annotation;
  3. /**
  4. * 使用反射读取注解的信息,模拟处理注解信息的流程
  5. * @author lyy
  6. *
  7. */
  8. public class Demo3 {
  9. public static void main(String[] args) {
  10. try {
  11. Class cls = Class.forName("com.lyy.test.annotion.Student");
  12. //获取类的所有注解
  13. Annotation[] annction = cls.getAnnotations();
  14. for (Annotation a :annction) {
  15. System.out.println(a);
  16. }
  17. //获取类中指定的注解
  18. Table tab = (Table)cls.getAnnotation(Table.class);
  19. System.out.println(tab.value());
  20. //获得类的属性的注解
  21. java.lang.reflect.Field f = cls.getDeclaredField("studentName");
  22. Field fx = f.getAnnotation(Field.class);
  23. System.out.println(fx.columName()+"====="+fx.type()+"====="+fx.length());
  24. //根据获取的表名、字段的信息、拼出DDL语句、然后,使用JDBC执行这个SQL,在数据库中生成相关的表
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30. </span>



  
  1. package com.lyy.test.annotion;
  2. @Table("tb_student")
  3. public class Student {
  4. @Field(columName="id",type="int",length=100)
  5. private int id;
  6. @Field(columName="sname",type="varchar",length=100)
  7. private String studentName;
  8. @Field(columName="age",type="int",length=3)
  9. private int age;
  10. public int getId() {
  11. return id;
  12. }
  13. public void setId(int id) {
  14. this.id = id;
  15. }
  16. public String getStudentName() {
  17. return studentName;
  18. }
  19. public void setStudentName(String studentName) {
  20. this.studentName = studentName;
  21. }
  22. public int getAge() {
  23. return age;
  24. }
  25. public void setAge(int age) {
  26. this.age = age;
  27. }
  28. <strong>
  29. }
  30. </strong>


  
  1. package com.lyy.test.annotion;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. import javax.lang.model.element.Element;
  7. @Target(value={ElementType.TYPE})
  8. @Retention(RetentionPolicy.RUNTIME)
  9. public @interface Table {
  10. String value();
  11. }


  
  1. package com.lyy.test.annotion;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Target(value={ElementType.FIELD})
  7. @Retention(RetentionPolicy.RUNTIME)
  8. public @interface Field {
  9. String columName();
  10. String type();
  11. int length();
  12. }


输出结果:




了解完这些后,你会发现,这个和hibernate的原理是不是很像,使用注解来标识,利用反射获取表名、字段和类型然后动态的创建sql语句封装,最后给程序员们使用,如果自己多做一点,你也可以做出一个简易的hibernate,学完这些发现自己仿佛又发现了一个好玩的东西,学无止境,加油!


案例下载:http://download.csdn.net/detail/qq_14996421/9539972


文章来源: muxiaonong.blog.csdn.net,作者:牧小农,版权归原作者所有,如需转载,请联系作者。

原文链接:muxiaonong.blog.csdn.net/article/details/51576370

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。