`
whp0731
  • 浏览: 174801 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java5.0新特性总结--Annotation系统学习整理笔记

    博客分类:
  • J2SE
阅读更多

Java Annotation特性与使用方式
一、为什么使用Annotation
在JAVA应用中,我们常遇到一些需要使用模版代码的情况。例如,为了编写一个 web service,我们必须提供一对接口和实现作为模版代码。如果使用annotation对远

程访问的方法代码进行修饰的话,这个模版就能够使用工具自动生成。
另外,一些API需要使用与程序代码同时维护的附属文件。例如EJB需要一个部署描述符。此时在程序中使用annotation来维护这些附属文件的信息将十分便利而且减少

了错误。

二、Annotation工作方式(应知道如何定义,如何使用)
从Java5.0版发布以来,5.0平台提供了一个正式的annotation功能:允许开发者定义、使用自己的annotation类型。此功能由一个定义annotation类型的语法和一个描

述annotation声明的语法,读取annotation的API,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。
annotation并不直接影响代码语义,但是它能够工作的方式被看作类似程序的工具或者类库,它会反过来对正在运行的程序语义有所影响。annotation可以从源文件、

class文件或者以在运行时反射的多种方式被读取。
当然annotation在某种程度上使javadoc tag更加完整。一般情况下,如果这个标记对java文档产生影响或者用于生成java文档的话,它应该作为一个javadoc tag;否

则将作为一个annotation。

三、使用JDK5内建Annotation
参见程序实例
Override
Deprecated
SuppressWarnings

 

 1、Override重写(子类、父类间关系)而overload(重载,方法间)

Override强制的保障已经覆盖了父类的方法, 如此处toString()大写成ToString(),它就会提示你出错了。

public class OverrideTest
{
	@Override
	public String toString()
	{
		return "This is override";
	}

	public static void main(String[] args)
	{
		OverrideTest test = new OverrideTest();

		System.out.println(test.toString());
	}
}

 2、Deprecated
被@Deprecated标示的方法是一个不建议被使用的方法

DeprecatedTest.java,申明作者以前定义的方法doSomething可能会有问题,不介意使用了!

当你再去使用或者再从该类去继承都会出现警告信息!

public class DeprecatedTest
{
	@Deprecated
	public void doSomething()
	{
		System.out.println("do something");
	}
	
	public static void main(String[] args)
	{
		DeprecatedTest test = new DeprecatedTest();
		test.doSomething();
	}
}

 3、SuppressWarnings

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

public class SuppressWarningsTest
{//仅去掉集合的警告如下:@SuppressWarnings("unchecked")
	//以下表示压制住两个类型的警告
	@SuppressWarnings({"unchecked","deprecation"})
	public static void main(String[] args)
	{//没有用泛型,在jdk1.5,会出现警告!
		Map map = new TreeMap();	
		map.put("hello",new Date());
		
		System.out.println(map.get("hello"));
		
		DeprecatedTest test = new DeprecatedTest();
		test.doSomething();
		
	}
}

 


四、自定义Annotation类型

使用@interface自行定义Annotation型态时,实际上是自动继承了java.lang.annotation.Annotation接口;;如果我们手工地显示地区定义一个接口public interface test

extents Annotation,这个test接口不是Annotation。
它要隐式地为你实现,由编译程序自动为您完成其它产生的细节
在定义Annotation型态时,不能继承其它的Annotation型态或是接口

 

public @interface AnnotationTest//这个后面不能显示地再去继承别的接口
{
 //在Annotation类中定义属性方法,需要多一个小括号
 //例如:String value();
 //然后在使用的地方需要对这个value赋值,如在别的 类中需要@AnnotationTest(value="hello world")
 //value是默认表述,可以省略@AnnotationTest("hello world"),但如果改成value1必须显示申明
 String value();
}

 

 

 

 

 

 

@AnnotationTest("hello world")
public class AnnotationUsage
{
	public void method()
	{
		System.out.println("usage of annotation");
	}

	public static void main(String[] args)
	{
		AnnotationUsage usage = new AnnotationUsage();
		usage.method();
	}
}

 

扩展以上两个例子

package com.test;
public @interface AnnotationTest
{
	//在Annotation类中定义属性方法,需要多一个小括号
	//例如:String value();
	//然后在使用的地方需要对这个value赋值,如在别的 类中需要@AnnotationTest(value="hello world")
	//value是默认表述,可以省略@AnnotationTest("hello world"),但如果改成value1必须显示申明
	String value() default "ok";//用defaulf关键字可以定义默认值
	
	//枚举类型的value1,默认值是hello
	//EnumTest value1() default EnumTest.Hello;
	
	//String[] value2();
}

enum EnumTest
{
	Hello, World, Welcome;
}

 

package com.langsin.test;
@com.test.AnnotationTest(value="hello world")//或者可以导入包import com.test然后写成AnnotationTest(value="hello world")//@AnnotationTest(value1="EnumTest.World")
//@AnnotationTest(value2={"hello","world"})

public class AnnotationUsage
{
	public void method()
	{
		System.out.println("usage of annotation");
	}

	public static void main(String[] args)
	{
		AnnotationUsage usage = new AnnotationUsage();
		usage.method();
	}
}

 


五、告知编译程序如何处理@Retention 

 

 java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您的自定义的Annotation型态
预设上编译程序会将Annotation信息留在.class档案中,但不被虚拟机读取,而仅用于编译程序或工具程序运行时提供信息

在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy的枚举型态{}中为它的三个级别!
package java.lang.annotation;
public enum RetentionPolicy
 {
  SOURCE, //编译程序处理完Annotation信息后就完成任务(被编译程序废弃)
  CLASS,  //编译程序将Annotation储存于class档中,缺省
  RUNTIME //编译程序将Annotation储存于class檔中,可由jVM读入(可以通过反射方式读取注解相关信息)
}

 

 

RetentionPolicy为SOURCE的例子是@SuppressWarnings
仅在编译时期告知编译程序来抑制警告,所以不必将这个信息储存于.class档案
RetentionPolicy为RUNTIME的时机,可以像是您使用Java设计一个程序代码分析工具,您必须让VM能读出Annotation信息,以便在分析程序时使用
搭配反射(Reflection)机制,就可以达到这个目的

 

 如何使用?以下程序为演示程序
演示程序

1、Annotation类的定义中不能定义日期类变量、也不能定义二维数组。

2、AnnotatedElement接口介绍
<T extends Annotation> T         getAnnotation(Class<T> annotationType)
                                 Returns this element's annotation for the specified type if such an annotation is present, else null.
                               
Annotation[] getAnnotations()    Returns all annotations present on this element.


Annotation[] getDeclaredAnnotations()
                                 Returns all annotations that are directly present on this element.(即不包括父类)

 

boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
                                 Returns true if an annotation for the specified type is present on this element, else false.
3、程序介绍

 

package com.langsin.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{
 String hello() default "langsin";
 String world();
}



package com.langsin.annotation;

@MyAnnotation(hello = "beijing", world = "shanghai")
public class MyTest
{
 @MyAnnotation(hello = "beijing", world = "shanghai")
 @Deprecated
 @SuppressWarnings("unchecked")
 public void output()
 {
  System.out.println("output something");
 }
}




package com.langsin.annotation;

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

public class MyReflection
{
 public static void main(String[] args) throws Exception
 {
  MyTest myTest = new MyTest();
  
  Class<MyTest> c = MyTest.class;
  
  Method method = c.getMethod("output",new Class[]{});
  
  if(method.isAnnotationPresent(MyAnnotation.class))
  {
   method.invoke(myTest,new Object[]{});
   //以下方法的具体含义可以参见AnnotatedElement接口介绍的具体介绍!
   MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
   //myAnnotation.hello();这句话的意思是此时的MyAnnotation的属性需要按按类似方法的式样进行调用。
   String hello = myAnnotation.hello();
   String world = myAnnotation.world();
   
   System.out.println(hello);
   System.out.println(world);
   
  }
  
  Annotation[] annotations = method.getAnnotations();
  
  for(Annotation annotation : annotations)
  {
   System.out.println(annotation.annotationType().getName());
  }
  
 }
} 

/*
 * 运行结果
output something
beijing
shanghai
com.langsin.annotation.MyAnnotation
java.lang.Deprecated
说明:为什么运行结果中没有java.lang.SuppressWarnings。因为在jdk文档中我们可以发现SuppressWarnings的定义中为@Retention(value=SOURCE)
而 SOURCE, //编译程序处理完Annotation信息后就完成任务(被编译程序废弃)
   CLASS,  //编译程序将Annotation储存于class档中,缺省
   RUNTIME //编译程序将Annotation储存于class檔中,可由jVM读入(可以通过反射方式读取注解相关信息)
   也就是说只有当@Retention的value值为RUNTIME时才会被虚拟机运行时加载!

*/

 

六、限定annotation使用对象@Target
1、使用java.lang.annotation.Target可以定义其使用之时机
在定义时要指定java.lang.annotation.ElementType的枚举值之一
package java.lang.annotation;
public enum ElementType
{
     TYPE, //适用class, interface, enum
     FIELD, //适用field
     METHOD, //适用method
     PARAMETER, //适用method上之parameter
     CONSTRUCTOR, //适用constructor
     LOCAL_VARIABLE, //适用局部变量
     ANNOTATION_TYPE, //适用annotation型态
     PACKAGE //适用package

}


2、程序举例
package com.langsin.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
//定义完以上@Target(ElementType.METHOD),以后MyTarget这个Annotation只能用在方法上了!
public @interface MyTarget
{
 String value();
}


package com.langsin.annotation;
public class MyTargetTest
{
 @MyTarget("xyz")
 public void doSomething()
 {
  System.out.println("hello world");
 }
}


七、要求为API文件@Documented
1、想要在使用者制作JavaDoc文件的同时,也一并将Annotation的讯息加入至API文件中
使用java.lang.annotation.Documented

2、程序举例

package com.langsin.annotation;

import java.lang.annotation.Documented;

@Documented//这句话的意思是生成doc文档时,包括annotation的信息。
public @interface DocumentedAnnotation
{
 String hello();
}


package com.langsin.annotation;

public class DocumentedTest
{
 /**
  * This is the comments that I have added
  */
 @DocumentedAnnotation(hello = "welcome")
 public void method()
 {
  System.out.println("hello world");
 }
}

 

八、子类是否继承父类@Inherited
1、预设上父类别中的Annotation并不会被继承至子类别中
可以在定义Annotation型态时加上java.lang.annotation.Inherited型态的Annotation

2、程序举例

package com.langsin.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@Inherited//这个注解决定了使用这个Annotation的类,子类可以继承他的Annotation!
//但是这个注解只能在类的级别上才能起作用,若是实现接口层次上,不会被继承
public @interface InheritedTest
{
 String value();
}

package com.langsin.annotation;
@InheritedTest("langsin")
public class Parent
{
 public void doSomething()
 {
  System.out.println("hello");
 }
}


package com.langsin.annotation;
public class Child extends Parent
{
 
}


package com.langsin.annotation;
public class Test
{
 public static void main(String[] args)
 {
  Class<Child> c = Child.class;
  
  if(c.isAnnotationPresent(InheritedTest.class))
  {
   InheritedTest inheritedTest = c.getAnnotation(InheritedTest.class);
   String value = inheritedTest.value();
   System.out.println(value);
  }
 }
}

 

 

附:项目组总结的annotation的应用。 Annotation -Junit,Spring,Hibernate应用.rar

分享到:
评论

相关推荐

    良葛格java jdk 5.0学习笔记

    这些新特性极大地提升了Java的生产力和代码质量,使得Java JDK 5.0成为了一个里程碑式的版本。学习这些内容对于理解现代Java编程至关重要。通过良葛格的Java JDK 5.0学习笔记,读者可以深入理解这些核心概念,并在...

    良葛格Java JDK 5.0学习笔记

    在Java 5.0这个版本中,许多新特性被引入,极大地提升了开发效率和代码的可读性。 首先,我们来看看Java 5.0的重要更新之一:泛型。泛型是Java 5.0引入的革命性特性,它允许在定义类、接口和方法时指定类型参数,...

    java jdk5.0学习笔记——良葛格

    Java JDK 5.0是Java开发工具包的一个重要版本,它在2004年发布,引入了许多新特性,极大地增强了Java编程语言的功能和效率。良葛格的《Java JDK5.0学习笔记》是一本面向初学者的教程,旨在帮助读者掌握这个版本的...

    java学习笔记 初学者必读

    17. java5.0的新特性 17-59 17.1. 泛型 17-59 17.1.1. 说明 17-59 17.1.2. 用法 17-60 17.1.3. 泛型的通配符"?" 17-62 17.1.4. 泛型方法的定义 17-63 17.1.5. 泛型类的定义 17-63 17.1.6. 泛型与异常 17-64 17.1.7. ...

    Hibernate Annotation 学习笔记

    《Hibernate Annotation 学习笔记》 在Java的持久化框架中,Hibernate以其强大的功能和易用性成为开发者首选之一。而Hibernate Annotation则是Hibernate提供的一种基于注解的实体映射方式,它极大地简化了传统XML...

    良葛格的java学习笔记全

    14. **注解(Annotation)**:注解是Java 5.0的新特性,用于向编译器或JVM提供元数据,可以用于代码生成、验证、监控等场景。 15. **垃圾回收(Garbage Collection)**:Java的自动内存管理机制,理解其工作原理和...

    Java/JavaEE 学习笔记

    第一章 Java5.0新特性.......................94 第二章 基础知识.....96 第三章 泛型...........101 第四章 Annotation.102 XML学习笔记...............106 XML前言...............106 第一章 XML Overview..........

    JavaEE学习笔记

    Tiger是指Java 5.0版本(也称为JDK 1.5),这一版引入了许多新特性,例如泛型、注解(Annotation)、自动装箱等。这些新特性极大地提高了Java语言的表达能力和开发效率,是学习Java EE必须掌握的知识点。 XML学习...

    java学习笔记

    Java学习笔记是一个专门为初学者设计的学习资源,涵盖了Java编程的基础概念和核心特性。...同时,了解并实践Java 5的新特性,能够帮助开发者编写出更高效、更易于维护的代码,为日后的进阶学习打下坚实基础。

    MLDN老师java笔记(全面 必看)

    泛型是Java SE 5.0引入的新特性,用于在编译时检查类型安全,并能提高代码的重用率。泛型可以应用于类、接口和方法。 【注解】 注解(Annotation)是元数据的一种形式,可以提供有关代码的附加信息。编译器和JVM...

    java编程思想读书笔记

    13. **泛型**:泛型是Java SE 5.0引入的新特性,用于在编译时检查类型安全,并且可以用来消除装箱和拆箱操作,提高代码效率。 14. **枚举**:Java的枚举类型是一种特殊的类,用于定义有限数量的值,提供了比常量更...

Global site tag (gtag.js) - Google Analytics