Annotaion 注解 详解案例

1、注解入门

2、内置注解

3、自定义注解、元注解

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

1、注解入门

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

Annotation的作用:

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

Annotation的格式:

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

Annotation在哪里使用

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

2、内置注解

@Override

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

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

package java.lang;

import java.lang.annotation.*;

/**
 * 表示方法声明的目的是重写
 * 在父类方法声明。如果一个方法被注释
 * 此注释类型编译器将生成一个错误
 * 除非下列情况中至少有下列情况之一:
 *
 * <ul><li>
 * 该方法是否重写或实现在一个声明中声明的方法
 * 超类.
 * </li><li>
 * 该方法具有一个与该等效的签名
 * 任何公开声明的方法在 {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ahé
 * @author  Joshua Bloch
 * @jls 9.6.1.4 Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface 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<strong> </strong>程序元素的注释 是一个程序员使用
 * 不要使用,通常是因为它是危险的,
 * 或因为一个更好的选择存在。编译器发出警告
 * 过时的程序元素的使用或重写非过时的代码。
 *
 * @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.*;

/**
 * 指示将被命名为编译器警告
 * 注释的元素(以及在注释中包含的所有程序元素中的
 * 元素)。请注意,在一个给定的元素中被抑制的一组警告
 * 警告抑制所有包含元素的一个超集。对于
 * 例如,如果您注释一个类,以抑制一个警告和注释
 * 方法来抑制另一个,这两个警告将被抑制的方法。
 *
 * <p>作为一种风格,程序员应该经常使用这个注释
 * 在最深层嵌套元素,它是有效的。如果你想
 * 在特定的方法中抑制警告,您应该批注
 * 方法,而不是其类。
 *
 * @since 1.5
 * @author Josh Bloch
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * 在编译器中被抑制的警告集
     * 注释元素。允许重复名称。第二
     * 连续出现的名称被忽略。在场的
     * 无法识别的警告名称是不一个错误:编译器必须
     * 忽略任何警告名称,他们不承认。然而,他们是,
     * 如果一个注释包含一个未被识别的,自由发出警告
     * 警告名称。
     *
     * <p>编译器供应商应该记录他们支持的警告名称
     * 与此注释类型一起使用。鼓励他们合作
     * 确保在多个编译器上工作相同的名称。
     */
    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 <del>testoo1</del>(){
		System.out.println("test.001");
	}

	public static void test002(){
		List list = new ArrayList<>();
	}

	public static void main(String[] args) {
		Date d = new Date();
		<del>testoo1</del>();
	}
}

@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

package com.lyy.test.annotion;

@SxtMyAnnotation
public 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、小案例

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

<span style="font-size:14px;">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();
		}

	}

}
</span>
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;
	}

	<strong>
}
</strong>
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,学完这些发现自己仿佛又发现了一个好玩的东西,学无止境,加油!

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

时间: 2024-10-20 11:06:30

Annotaion 注解 详解案例的相关文章

【转】@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

@RequestParam @RequestBody @PathVariable 等参数绑定注解详解 2014-06-02 11:24 23683人阅读 评论(2) 收藏 举报 目录(?)[+] 引言: 接上一篇文章,对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: 简介: handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主

Spring中常用的配置和注解详解

一.  Spring中常用的配置文件详解 Spring中的配置文件详解 1.<!-- 配置注解bean的扫描路径 该配置表示从cn包下开始扫描--> <context:component-scan base-package="cn"></context:component-scan> 2.<!-- 加载资源文件 其中Location表示从哪个路径加载配置文件properties--> <context:property-placeh

【第11篇】最全的中文TypeScript入门指南详解案例教程与代码案例

一.最全的中文TypeScript入门指南详解案例教程           文档下载 二.代码案例 源代码下载 手机微信扫一扫有惊喜... ================================================================================================================= 1.详细安装文章请看 http://blog.csdn.net/jilongliang/article/details/219429

自动化运维工具——ansible详解案例分享

自动化运维工具--ansible详解案例分享(一)目录ansible 简介ansible 是什么?ansible 特点ansible 架构图ansible 任务执行ansible 任务执行模式ansible 执行流程ansible 命令执行过程ansible 配置详解ansible 安装方式使用 pip(python的包管理模块)安装使用 yum 安装ansible 程序结构ansible配置文件查找顺序ansible配置文件ansuble主机清单ansible 常用命令ansible 命令集a

Java——注解详解

Java注解同 classs 和 interface 一样,注解也属于一种类型.它是在 Java SE 5.0 版本中开始引入的概念. 注解的定义 通过 @interface 关键字进行定义. public @interface TestAnnotation { } 这段代码就创建了一个名字为 TestAnnotaion 的注解. 你可以简单理解为创建了一张名字为 TestAnnotation 的标签. 使用注解 @TestAnnotation public class Test { } 在类上

Java基础13:反射与注解详解

Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Oracle官方对反射的解释是 Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fi

java 动态性之反射机制 详解 案例

1.反射机制 2.动态编译 3.动态执行javassript代码 4.动态字节码操作 动态语言 程序运行时,可以改变程序结构或变量类型.典型的语言: 1):Python.ruby.javascript等. 2):如下javascript代码: funtion test(){ var s ="var a=3;var b=5;alert(a+b);"; eval(s); } 3):C,C++,JAVA不是动态语言,JAVA可以称之为"准动态语言".但是JAVA有一定的动

springMVC的注解详解

springmvc常用注解标签详解 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示.在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@Request

【转】Spring注解详解

http://blog.csdn.net/xyh820/article/details/7303330/ 概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名.类型等信息,如果关系表字段和 PO 属性名.类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取. 注释和 Java 代码位于一个文件中,而