Java注解

Java 注释提供有关代码的信息。Java 注释对其所注释的代码没有直接影响。在 Java 注释教程中,我们将研究以下内容;

    1. 内置的Java注释

 

    1. 如何编写自定义注释

 

    注释的使用以及如何使用反射API解析注释。

Java注解

Java 1.5 引入了注解,现在在 Java EE 框架中,如 Hibernate、Jersey 和 Spring 中广泛使用。Java 注解是嵌入在程序本身中的关于程序的元数据。它可以被注解解析工具或编译器解析。我们还可以指定注解的可用性,要么只在编译时,要么持续到运行时。在 Java 注解之前,程序的元数据可以通过 Java 注释或 Javadoc 获取,但是注解提供了更多功能。注解的元数据也可以在运行时可用,并且注解解析器可以使用它来确定处理流程。例如,在 Jersey Web 服务中,我们在方法中添加 PATH 注解和 URI 字符串,而在运行时,Jersey 解析它以确定给定 URI 模式要调用的方法。

Java自定义注解

创建自定义注解类似于编写接口,唯一不同之处在于在接口关键字的前面加上_@_符号。我们可以在注解中声明方法。让我们看一个Java自定义注解的例子,然后我们将讨论它的特点和重要的要点。

package com.Olivia.annotations;

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;

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
	String author() default "Pankaj";
	String date();
	int revision() default 1;
	String comments();
}

关于java注解的一些重要点有:

    1. 注解方法不能有参数。

 

    1. 注解方法的返回类型限制为原始类型、String、Enums、注解或这些类型的数组。

 

    1. Java注解方法可以有默认值。

 

    注解可以附加元注解。元注解用于提供关于注解的信息。

Java中的元注解

有五种类型的元注释。

    1. 被@Documented注解的元素表示应该由javadoc和类似工具进行文档化。这种类型应该用于注释对其客户端使用有影响的类型声明。如果一个类型声明被注解为@Documented,那么它的注解将成为被注释元素的公共API的一部分。

 

    1. @Target注解表示注解类型适用于哪些程序元素。一些可能的值有TYPE、METHOD、CONSTRUCTOR、FIELD等。如果没有存在Target元注解,则注解可以用于任何程序元素。

 

    1. @Inherited注解表示注解类型自动继承。如果用户查询一个类声明的注解类型,并且该类声明没有该类型的注解,则将自动查询该类的父类是否有该注解类型。这个过程将重复进行,直到找到该类型的注解,或者到达类层次结构的顶部(Object)。

 

    1. @Retention注解表示带有该注解的注解类型保留多长时间。它接受一个RetentionPlicy参数,可能的值有SOURCE、CLASS和RUNTIME。

 

    @Repeatable用于指示注解类型声明的注解类型是可重复的。

Java中的内置注释

Java 提供了五个内置的注解。

    1. @Override – 当我们想要覆盖父类的方法时,应该使用这个注解来告诉编译器我们正在覆盖一个方法。所以当父类的方法被删除或者改变时,编译器会显示错误信息。了解为什么在覆盖方法时应该始终使用Java的覆盖注解。

@Deprecated – 当我们希望编译器知道一个方法已经过时时,应该使用这个注解。Java建议在javadoc中提供为什么这个方法已经过时以及替代方法的信息。

@SuppressWarnings – 这只是告诉编译器忽略它们产生的特定警告,例如在Java泛型中使用原始类型。它的保留策略是SOURCE,并且会被编译器丢弃。

@FunctionalInterface – 这个注解在Java 8中引入,表示该接口被设计为一个函数式接口。

@SafeVarargs – 程序员断言被注解方法或构造函数的主体在其varargs参数上不执行潜在的不安全操作。

Java注解示例

让我们看一个Java示例,展示了Java中内置注解的使用,以及我们在上述示例中创建的自定义注解的使用。

package com.Olivia.annotations;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class AnnotationExample {

	public static void main(String[] args) {
	}

	@Override
	@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
	public String toString() {
		return "Overriden toString method";
	}

	@Deprecated
	@MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
	public static void oldMethod() {
		System.out.println("old method, don't use it.");
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
	public static void genericsTest() throws FileNotFoundException {
		List l = new ArrayList();
		l.add("abc");
		oldMethod();
	}

}

我相信上述的Java注解示例是自我解释的,并展示了在不同情况下使用注解的用途。

解析 Java 注解

我们使用反射来解析Java类的注解。请注意,注解的保留策略应为RUNTIME,否则在运行时将无法获取其信息,我们将无法从中提取任何数据。

package com.Olivia.annotations;

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

public class AnnotationParsing {

	public static void main(String[] args) {
		try {
			for (Method method : AnnotationParsing.class.getClassLoader()
					.loadClass(("com.Olivia.annotations.AnnotationExample")).getMethods()) {
				// checks if MethodInfo annotation is present for the method
				if (method.isAnnotationPresent(com.Olivia.annotations.MethodInfo.class)) {
					try {
						// iterates all the annotations available in the method
						for (Annotation anno : method.getDeclaredAnnotations()) {
							System.out.println("Annotation in Method '" + method + "' : " + anno);
						}
						MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
						if (methodAnno.revision() == 1) {
							System.out.println("Method with revision no 1 = " + method);
						}

					} catch (Throwable ex) {
						ex.printStackTrace();
					}
				}
			}
		} catch (SecurityException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}

上述程序的输出是:

Annotation in Method 'public java.lang.String com.Olivia.annotations.AnnotationExample.toString()' : @com.Olivia.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.Olivia.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.Olivia.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.Olivia.annotations.AnnotationExample.oldMethod()' : @com.Olivia.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.Olivia.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.Olivia.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.Olivia.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)

Java反射API非常强大,在Java中广泛被使用,尤其在J2EE框架如Spring、Hibernate和JUnit中。请查看Java中的反射。以上是关于Java注解示例教程的全部内容,希望您从中学到了一些知识。Java注解的更新内容如下:

    1. Servlet规范3.0引入了用于Servlet配置和初始化参数的注释,可以在Java Servlet教程中了解更多信息。

 

    我们可以在Struts 2中使用注释来配置其操作类和结果页面,可以在Struts 2 Hello World注释示例中查看工作示例。

参考资料:Oracle官方网站

广告
将在 10 秒后关闭
bannerAds