Annotaion 注解 详解案例

网友投稿 268 2022-11-19

Annotaion 注解 详解案例

1、注解入门

2、内置注解

3、自定义注解、元注解

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

1、注解入门

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

Annotation的作用:

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

Annotation的格式:

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

Annotation在哪里使用

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

2、内置注解

@Override

@Depercated

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

/* * Copyright (c) 2003, 2010, 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.*;/** * @Deprecated 程序元素的注释 是一个程序员使用 * 不要使用,通常是因为它是危险的, * 或因为一个更好的选择存在。编译器发出警告 * 过时的程序元素的使用或重写非过时的代码。 * * @author Neal Gafter * @since 1.5 */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})public @interface Deprecated {}

@SuppressWarnings

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

/* * Copyright (c) 2004, 2011, 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.*;/** * 指示将被命名为编译器警告 * 注释的元素(以及在注释中包含的所有程序元素中的 * 元素)。请注意,在一个给定的元素中被抑制的一组警告 * 警告抑制所有包含元素的一个超集。对于 * 例如,如果您注释一个类,以抑制一个警告和注释 * 方法来抑制另一个,这两个警告将被抑制的方法。 * *

作为一种风格,程序员应该经常使用这个注释 * 在最深层嵌套元素,它是有效的。如果你想 * 在特定的方法中抑制警告,您应该批注 * 方法,而不是其类。 * * @since 1.5 * @author Josh Bloch */@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.SOURCE)public @interface SuppressWarnings { /** * 在编译器中被抑制的警告集 * 注释元素。允许重复名称。第二 * 连续出现的名称被忽略。在场的 * 无法识别的警告名称是不一个错误:编译器必须 * 忽略任何警告名称,他们不承认。然而,他们是, * 如果一个注释包含一个未被识别的,自由发出警告 * 警告名称。 * *

编译器供应商应该记录他们支持的警告名称 * 与此注释类型一起使用。鼓励他们合作 * 确保在多个编译器上工作相同的名称。 */ String[] value();}

使用这些内置注解

package com.lyy.test.annotion;import java.util.ArrayList;import java.util.Date;import java.util.List;@SuppressWarnings("all")public class Demo1 /*extends Object*/{ @Override public String toString(){ return ""; } @Deprecated public static void testoo1(){ System.out.println("test.001"); } public static void test002(){ List list = new ArrayList<>(); } public static void main(String[] args) { Date d = new Date(); testoo1(); }}

@SuppressWanings

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

参数                                                           说明

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

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

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

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

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

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

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

3、自定义注解和元注解

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

要点:

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

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

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

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

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

package com.lyy.test.annotion;@SxtMyAnnotationpublic class Demo2 { @SxtMyAnnotation(age=19,studentName="泡泡", id=1001,schools={"北京大学","孝感学院"}) public void test(){ } @SxtAnnotation2("1") public void test2(){ } }

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

package com.lyy.test.annotion;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(value={ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface SxtAnnotation2 { String value();}

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

4、小案例

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

package com.lyy.test.annotion;import java.lang.annotation.Annotation;/** * 使用反射读取注解的信息,模拟处理注解信息的流程 * @author lyy * */public class Demo3 { public static void main(String[] args) { try { Class cls = Class.forName("com.lyy.test.annotion.Student"); //获取类的所有注解 Annotation[] annction = cls.getAnnotations(); for (Annotation a :annction) { System.out.println(a); } //获取类中指定的注解 Table tab = (Table)cls.getAnnotation(Table.class); System.out.println(tab.value()); //获得类的属性的注解 java.lang.reflect.Field f = cls.getDeclaredField("studentName"); Field fx = f.getAnnotation(Field.class); System.out.println(fx.columName()+"====="+fx.type()+"====="+fx.length()); //根据获取的表名、字段的信息、拼出DDL语句、然后,使用JDBC执行这个SQL,在数据库中生成相关的表 } catch (Exception e) { e.printStackTrace(); } } }

package com.lyy.test.annotion;@Table("tb_student")public class Student { @Field(columName="id",type="int",length=100) private int id; @Field(columName="sname",type="varchar",length=100) private String studentName; @Field(columName="age",type="int",length=3) private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

package com.lyy.test.annotion;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import javax.lang.model.element.Element;@Target(value={ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Table { String value();}

package com.lyy.test.annotion;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(value={ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface Field { String columName(); String type(); int length();}

输出结果:

当然光使用自定义注解是不行的,你会发现当我们定义了这些自定义注解后,好像没有什么作用,这是因为没有让注解生效,我们需要利用反射来对注解进行解析生效,这个会在下篇文章中详细讲出!

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:springboot分布式整合dubbo的方式
下一篇:STM32基本系统主要几个部分
相关文章

 发表评论

暂时没有评论,来抢沙发吧~