Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容。在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解。
Java1.5引入了注解,当前许多java框架中大量使用注解,如Hibernate、Jersey、Spring。注解作为程序的元数据嵌入到程序当中。注解可以被一些解析工具或者是编译工具进行解析。我们也可以声明注解在编译过程或执行时产生作用。
在使用注解之前,程序源数据只是通过java注释和javadoc,但是注解提供的功能要远远超过这些。注解不仅包含了元数据,它还可以作用于程序运行过程中、注解解释器可以通过注解决定程序的执行顺序。例如,在Jersey webservice 我们为方法添加URI字符串的形式的PATH注解,那么在程序运行过程中jerser解释程序将决定该方法去调用所给的URI。
创建Java自定义注解
创建自定义注解和创建一个接口相似,但是注解的interface关键字需要以@符号开头。我们可以为注解声明方法。我们先来看看注解的例子,然后我们将讨论他的一些特性。
package com.journaldev.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内建注解
Java提供了三种内建注解。
我们来看一个java内建注解的例子参照上边提到的自定义注解。
package com.journaldev.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类的注解。那么注解的RetentionPolicy应该设置为RUNTIME否则java类的注解信息在执行过程中将不可用那么我们也不能从中得到任何和注解有关的数据。
package com.journaldev.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.journaldev.annotations.AnnotationExample')) .getMethods()) { // checks if MethodInfo annotation is present for the method if (method.isAnnotationPresent(com.journaldev.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.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)
这就是该教程的全部内容,希望你可以从中学到些东西。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
模板方法模式提供了抽象基类具有不可重写的方法:该方法实现了通用算法,不应在子类中重写。在Java中,模板方法在抽象基类中声明为final,在C中,sealed关键字具有类似的含义,但不能声明未重写的方法。 我如何解决这个问题?为什么不能阻止一个方法可以被子类重写(在C中)?
英文原文:http://emberjs.com/guides/templates/conditionals/ 有些时候,或许我们只希望在一个属性存在的时候显示一部分模板。 这时,我们就可以使用{{#if}}助手按条件渲染一个代码块,如下所示: 1 2 3 {{#if person}} Welcome back, <b>{{person.firstName}} {{person.lastNam
我对Java8的新特性有点陌生。我正在学习如何通过条目过滤地图。我已经看了这个教程和这个帖子我的问题,但我无法解决。
4 钩子方法的使用 模板方法模式中,在父类中提供了一个定义算法框架的模板方法,还提供了一系列抽象方法、具体方法和钩子方法,其中钩子方法的引入使得子类可以控制父类的行为。最简单的钩子方法就是空方法,代码如下: public virtual void Display() { } 当然也可以在钩子方法中定义一个默认的实现,如果子类不覆盖钩子方法,则执行父类的默认实现代码。
3 模板方法模式应用实例 下面通过一个应用实例来进一步学习和理解模板方法模式。 1. 实例说明 某软件公司欲为某银行的业务支撑系统开发一个利息计算模块,利息计算流程如下: (1) 系统根据账号和密码验证用户信息,如果用户信息错误,系统显示出错提示; (2) 如果用户信息正确,则根据用户类型的不同使用不同的利息计算公式计算利息(如活期账户和定期账户具有不同的利息计算公式); (3)
1. 模板方法模式概述 在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单。在这三个步骤中,点单和买单大同小异,最大的区别在于第二步——吃什么?吃面条和吃满汉全席可大不相同,如图1所示: 图1 请客吃饭示意图 在软件开发中,有时也会遇到类似的情况,某个方法的实