`

day_31Java注解---Annotation

阅读更多

星期二, 十二月 01, 2015 18:30:08   

 

给编译器看的注释---Annotation

 

       Annotation功能建立在反射机制之上,通过Annotation可以对程序进行注释操作。

系统内建Annotation、如何自定义Annotation、反射和Annotation的关联,

以及如何通过Annotation生产Docunmented。

 

本章要点

   掌握Annotation的相关概念

   熟悉自定义Annotation的方法

   了解反射和Annotation的关联

 

一、Annotation

 

    Annotation  实际上表示的是一种注释的语法。

在java中最早的程序是提倡程序与配置代码相分离,

而最新的理论是将所有的配置直接写到程序之中,如果想完成这样的功能,就要使用Annotation。

 

 

二、系统内建的Annotation

 

    在jdk1.5之后的系统中,内建了3个Annotation:

        @Override、@Deprecated、@SuppressWarinings。

 

2.1 @Override

    表示进行正确的覆写操作

 

   即使覆盖的方法名称写错了,也不会有任何的提示。

此时,为了保证程序可以正确地进行覆盖操作,在覆盖的时候可以明确地使用@Override表示方法是属于覆盖的操作。

  

 代码案例:

package day30;

public class OverrideTest {
	public static void main(String[] args) {
		Student s = new Student();
		System.out.print("..."+s.say());
	}
}
class Person {
	public String say() {
		return "Person_say()";
	}
}
//要求增加此类的子类,覆盖其方法
class Student extends Person {
/*为了保证程序可以正确地进行覆盖操作,
* 在覆盖的时候可以明确地使用@Override表示方法是属于覆盖的操作。*/
@Override
public String say() {
	return "Student_say()";
	}
}
 

 

运行结果:

...Student_say()

 

2.3@Deprecated

  @Deprecated注释表示不建议使用的操作。

例如之前在讲解线程的时候,曾经讲解过线程中的stop()、resume()、suspend()等方法是不建议使用的。

  

代码案例:

package day30;
 
public class DeprecatedTest {
	public static void main(String[] args) {
		System.out.print((new Info()).getInfo());
	}
}
 
class Info {
/*@Deprecated注释表示不建议使用的操作。*/
@Deprecated
	public String getInfo() {
		return "getInfo()....";
	}
}

 

运行结果:

getInfo()....

 

2.4 @SuppressWarnings

 

 @SuppressWarnings表示的是压制警告。

如果有一些警告信息则可压制掉,不出现警告的提示。

 

@SuppressWarnings(“deprecation”)

 

使用SuppressWarnings操作的时候可以同时压制多个警告

通过SuppressWarnings的类,可以发现在此类中存在一个value的字符串数组。

 

 

 

Person类中既继承了Info类,又实现了序列化的接口,所有此时会出现多个警告。

或者可以明确的表示,是为SuppressWarnings中的value属性赋值。

 

代码案例:

 

package day30;
 
import java.io.Serializable;
 
public class SuppressWarningsTest {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		System.out.print((new Infos()).getInfos());
	}
}
 
class Infos {
	@Deprecated
	public String getInfos() {
		return "....getInfos";
	}
}
 
@SuppressWarnings(value = {"serial","deprecation"})
class Persona extends Infos implements Serializable {
/*Person类中既继承了Info类,又实现了序列化的接口,所此时会出现多个警告。*/
 
}

 

 

运行结果:

....getInfos

 

三、自定义Annotation

 

 

    3.1定义Annotation的语法

      public @interface Annotation的名称{}

 

   案例:

    public @interface MyAnnotation{

    }

 

如果现在使用此Annotation的话,若不在同一个包中,则需要导入,导入之后使用@的形式反问,语法@MyAnnotation

    @MyAnnotation

    public class Info{

    }

      

在一个Annotation中实际上也可以定义若干个属性。

       public @interface MyAnnotation{

                 public String key();

                 public String value();

       }

 

   在此时Annotation中定义了key和value两个变量,若此时要使用Annotation的话,则必须明确地给出具体的内容。

 

    @MyAnnotation(key="MLDN",value="www.baidu.com")

 

 

 

如果现在希望为一个Annotation设置默认内容的话,可以通过default完成。

       public @interface MyAnnotation{

                 public String key()  default “LXX”;

                 public String value() default “HA”;

       }

 

如果没有设置内容,则将默认值去除继续使用。

 

Annotation中的变量内容可以通过枚举指定范围。

 public enum Color {

     RED,GREEN,BLUE;

}

 

案例:

       

      public @interface MyAnnotation{

                 public String key()  default “LXX”;

                 public String value() default “HA”;

                 public Color color() default Color.RED;

       }

 

如果现在在Info类中使用Annotation的时候并没有指定其规定范围的内容,则会出现错误。

 

   @MyAnnotation(color = “red”)

      public class Info {

    }

 

Annotation中的变量还可以使用一个数组表示。

  public @interface MyAnnotation{

                 public String key()  default “LXX”;

                 public String value() default “HA”;

                 public Color color() default Color.RED;

    public String[] url();

       }

 

以后在使用的时候必须按照数组的方式操作。

    @MyAnnotation(url = {“www.baidu.com”,“www.baidu.com”})

      public class Info {

    }

 

四、Retention和RetentionPolicy

 

   

软件包 java.lang.annotation 

Retention 指示注释类型的注释要保留多久。

 

Retention本身是一个Annotation,其中的取值是通过RetentionPolicy这个枚举类型指定的范围。

 

在RetentionPolicy中规定了以下3个作用范围。

       1.只在源代码中起作用:public static final RetentionPolicy SOURCE

       2.只在编译之后的class中起作用: public static final RetentionPolicy CLASS

       3.在运行的时候起作用:public static final RetentionPolicy RUNTIME

如果一个Annotation要想起作用,则必须使用RUNTIME范围。

任何一个自定义Annotation都是继承了java.lang.annotation.Annotaion接口。

 

五、反射与Annotation

 

 

一个Annotation如果想起作用,则肯定要依靠反射机制。通过反射可以取得在一个方法上声明的Annotation的全部内容。

 

Field、Method、Constructor的父类上定义了以下与Annotation反射操作相关的方法。

 

1.取得全部的Annotation: public Annotation[] getAnnotations()

2.判断操作的是否是指定的Annotation。

  public boolean isAnnotationPresent(Class<? entends Annotation> annotationClass)

 

 

 

5.1 取得全部的Annotation

 

   代码案例:

package day30;

public class Info {
	
	@Override
	@Deprecated
	@SuppressWarnings(value="_")
	//现在在一个方法上使用3个内建的Annotation
	public String toString(){
		return "Hello";
	}
}

package day30;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class ClassAnnotationTest {
	public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException {
		Class<?> cls = Class.forName("day30.Info");
		Method mtd = cls.getMethod("toString");
		Annotation ant[] = mtd.getAnnotations();
		//取得全部的Annotation
		for(int i = 0;i<ant.length;i++) {
			System.out.print(""+ant[i]);
		}
	}
}

 运行结果:

@java.lang.Deprecated()

 

这3个内建的Annotation中只有@Deprecated是RUNTIME类型。

实践证明,如果在程序运行的时候当取得了全部的Annotation时,只能取得一个。

 

 

此案例很好的证明了只有在Runtime范围中国的自定义的才可以被用户找到。

 

 

5.2 加入自定义的Annotation

 

   在一个自定义的Annotation编写的时候,如果要想让其有意义,则必须使用RUNTIME声明范围。

@Retention(value = RetentionPolicy.RUNTIME)

 

代码案例:

package day30;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//在一个自定义的Annotation编写的时候,如果要想让其意义,则必须使用RUNTIME声明范围。
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String key() default "zhuhw";
	public String value();
}


此后在Info类中增加此Annotation

package day30;

public class Info {
	//此后在Info类中增加此Annotation
	@Override
	@Deprecated
	@SuppressWarnings(value="_")
	@MyAnnotation(key = "waxun",value = "www.baidu.com")
	//现在在一个方法上使用3个内建的Annotation
	public String toString(){
		return "Hello";
	}
}

在使用的时候真正需要取得的是向自定义Annotation中设置的内容

package day30;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationTest {
	public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException{
		Class<?> clsa = Class.forName("day30.Info");
		Method m2 = clsa.getMethod("toString");
		Annotation att[] = m2.getAnnotations();
		//取得全部的Annotation
		for(int i =0;i<att.length;i++) {
			if(m2.isAnnotationPresent(MyAnnotation.class)) {
				//声明Annotation对象
				MyAnnotation ma = null;
				ma = m2.getAnnotation(MyAnnotation.class);
				String key = ma.key();
				String value = ma.value();
				System.out.println(key+"-->"+value);
			}
		}
	}
}

 运行结果:

waxun-->www.baidu.com

waxun-->www.baidu.com

 

 

 

在实际开发中,不用关心这些低层的操作原理,在程序使用中都会为其提供支持。

 

 

六、深入Annotation

 

  在java.lang.annotation中存在以下的Annotation:

      Target、Documended、Inherited

 

一个自定义的Annotation可以在任意的位置使用

 

例如:

 

   @MyAnnotation

   public class Info{

@MyAnnotation

       private  String name;

       @MyAnnotation

       public String toString() {

         return "HELLO";

        }

   }

 

因为可以在任意的位置上使用,因此在操作的时候就会出现一些问题,例如一些Annotation只希望在方法的声明上使用。

那么此时,就必须设置Annotation的作用范围。

 

 

在@Target注释中,存在EleentType类型的变量,在此变量中存在7种范围。

    1.只能在Annotation中出现: public static final ElementType ANNOTATION_TYPE

    2.只能在构造方法中出现: public static final ElementType CONSTRUCTOR

    3.本地变量上使用:public static final ElementType LOCAL_VARIABLE

    4.只能在方法上使用: public static final ElementType METHOD

    5.在参数声明上使用: public static final ElementType PARAMETER

    6.在包声明上使用: public static final ElementType PACKAGE

    7.只能在类或接口上使用: public static final ElementType TYPE

 

例子:

package day30;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Target(value = ElementType.METHOD)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String key() default "zhuhw";
	public String value() default "waxun";
}

此Annotation只能在方法上使用。
或者可以同时制定多个范围。
 
例子:
package day30;

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})
//在一个自定义的Annotation编写的时候,如果要想让其意义,则必须使用RUNTIME声明范围。
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String key() default "zhuhw";
	public String value();
}

 6.2 Docunmented注释

   此种表示的是文档的注释格式

 

代码案例:

package day30;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String key() default "zhuhw";
	public String value();
}

在使用类中可以加入文档注释。


package day30;

@MyAnnotation
public class Info {
	private String name;
	/*
	 * 本方法是覆盖Obiect类中的toString()方法
	 */
	@MyAnnotation
	public String toString(){
		return "Hello";
	}
}

 加入文档注释后,程序的最大好处是可以在doc文档中出现。

在mye中直接支持javadoc文档的生成。

导出项目有一个javadoc文档的生成

 

 

 

6.3 Inherited

  表示一个Annotation能否被使用其类的子类继承下去。

如果没有写上此注释,则此Annotation根本就是无法继承。

 

案例:

package day30;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited
@Documented
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String key() default "zhuhw";
	public String value()default "waxun";
}

 此Annotation可以被子类继承。

 

星期二, 十二月 01, 2015 23:50:03

2
0
分享到:
评论

相关推荐

    Java基础_第二阶段-day16每日作业卷1

    总结起来,这个阶段的作业涵盖了单元测试的基本概念和使用,Java注解的定义、使用和作用,以及如何自定义注解以满足特定需求。这些知识对于理解和实践Java开发中的测试驱动开发(TDD)、代码质量控制以及元编程有着至...

    01day_01mybatis_java_

    5. **Mapper Annotation**: 除了 XML 配置,MyBatis 也支持在接口方法上使用注解来直接写 SQL,使得配置更简洁。 6. **动态 SQL**: MyBatis 的一大亮点是支持动态 SQL,可以在 XML 或注解中编写条件语句,避免了...

    java_spring_day05.pdf

    - 通过配置`&lt;tx:annotation-driven transaction-manager="transactionManager"/&gt;`启用注解驱动的事务管理。 - 使用`@Transactional`注解来标记需要事务处理的方法或类。 2. **编程式事务管理:** - 适用于复杂的...

    EJB注解说明

    在EJB 3.0版本中,引入了注解(Annotation)来简化组件的配置,使得实体Bean(Entity Bean)成为纯粹的Plain Old Java Object(POJO),与Hibernate持久化实体对象的概念相融合。这意味着开发者可以不再依赖于复杂的...

    spring mvc常用注解_动力节点Java学院整理

    Spring MVC常用注解 Spring MVC框架中大量使用了注解来简化开发过程,提高开发效率。下面我们将详细介绍Spring MVC中常用的注解。 1. @Controller注解 @Controller注解用于定义控制器,控制器是通过服务接口定义...

    day02_eesy_01anno_ioc_多线程_

    然而,随着Spring的发展,注解(Annotation)逐渐成为更受欢迎的配置方式。Spring提供了如`@Component`、`@Service`、`@Repository`和`@Controller`等注解,用于标记类作为Spring Bean。同时,`@Autowired`注解可以...

    Java_day15上课资料.zip

    【Java_day15上课资料】是针对Java编程语言的学习资源,通常包含课件、笔记、示例代码等,旨在帮助学员深入理解Java编程的核心概念和技术。在这个压缩包中,我们可能找到诸如PPT课件、PDF文档、源代码文件等,它们会...

    day18-xml、枚举和注解.zip

    注解(Annotation)是Java的一种元数据,提供了在源代码中添加信息的方式,这些信息可以被编译器或者JVM在编译期或运行期处理。注解可以用于简化代码维护、提供编译时或运行时的检查、生成代码、配置应用服务器等。...

    day021-反射和注解笔记和代码.rar

    枚举是一种类,注解(指的是注解Annotation)是一种接口; 每个数组都是 Class字节码类中的一个具体 对象 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示...

    week13_day2_annotations_hw

    描述中同样提到 "week13_day2_annotations_hw",这可能表示这是一个为期13周课程的第2天的作业,主题聚焦于Java注解。这意味着我们可能要探讨如何使用和理解不同类型的注解,以及它们在实际开发中的应用。 标签 ...

    day01_video.zip

    15. **注解(Annotation)**:注解是Java提供的一种元数据,可以用来提供编译时和运行时的信息。 16. **模块系统(Java 9+)**:Java 9引入了模块系统,改善了大型项目的可维护性和性能。 通过"day01_video"这个...

    Java_day22上课资料.zip

    9. **注解(Annotation)**:注解提供了一种元数据方式,可以用来标记代码,供编译器或运行时环境使用。 10. **Java集合框架的高级话题**:例如并发容器如ConcurrentHashMap,或者泛型的使用和限制。 以上内容只是...

    Java_day24上课资料.zip

    11. **注解(Annotation)**:注解是Java提供的一种元数据,可以用来提供编译器或JVM在编译时或运行时检查或修改程序的能力。 12. **泛型**:泛型是Java 5引入的新特性,允许在类、接口和方法中使用类型参数,增强...

    day03-菜品管理 day03-菜品管理

    - **注解(Annotation)**:在Java中,注解是一种元数据,提供了一种安全的方式来将信息附加到代码上。`AutoFill`注解就是这样一个例子,它可以指示哪些方法需要自动填充公共字段。 - **AOP(面向切面编程)**:...

    day13javacode

    8. **注解(Annotation)**:注解在代码中提供了元数据,用于编译器或运行时系统进行特殊处理。 9. **反射**:反射允许程序在运行时动态地获取类的信息并操作类的对象。 10. **设计模式**:学习一些常见的设计模式,...

    day01_基础加强_docx1

    注解(Annotation)是元数据的一种形式,用于提供有关代码的附加信息,可以被编译器或运行时环境读取。在测试中,注解如 @Test、@Before 和 @After 已经被讨论过。除此之外,Java 提供了一些内置注解,如 @Override ...

    Java_day26上课资料.zip

    "Java_day26上课资料.zip"这个压缩包文件很可能是某个在线课程或教学资源的一部分,旨在帮助学习者深入理解Java语言的核心概念和技术。从描述中的链接我们可以推测,这可能是一个关于Java的教学视频,与该压缩包的...

    day16_springboot_笔记

    Spring 2.x 引入了注解支持,允许开发者在 Java 类中使用注解来声明和注入 Bean,显著减少了 XML 配置的需求。然而,尽管注解简化了开发,但在大型项目中,仍然需要管理和阅读大量的配置类。因此,Spring 3.x 开始...

    千峰安卓培训Java目录,安卓开发前期Java培训 安卓开发Java培训day06

    10. **注解(Annotation)**:Java注解在安卓开发中用于元数据的标注,可以简化代码,提高可维护性,如@Override确保方法覆盖,@NonNull防止空指针异常。 11. **异常安全的编程实践**:在安卓开发中,良好的编程...

    day43_springmvc.zip

    5. **注解驱动(Annotation-based)**:Spring MVC广泛使用注解简化配置,如`@RequestMapping`、`@Controller`、`@Service`、`@Autowired`等,使得代码更加简洁且易于维护。 6. **数据绑定(Data Binding)**:Spring ...

Global site tag (gtag.js) - Google Analytics