文献部分
Abstract
The ability to annotate code and, in general, the capability to attach arbitrary meta-data to portions of a program are features that have become more and more common in programming languages.
Annotations in Java make it possible to attach custom, structured meta-data to declarations of classes, fields and methods. However, the mechanism has some limits: annotations can only decorate declarations and their instantiation can only be resolved statically.
With this work, we propose an extension to Java (named @Java) with a richer annotation model, supporting code block and expression annotations, as well as dynamically evaluated members. In other words, in our model, the granularity of annotations extends to the statement and expression level and annotations may hold the result of runtime-evaluated expressions.
Our extension to the Java annotation model is twofold: (i) we introduced block and expression annotations and (ii) we allow every annotation to hold dynamically evaluated values. Our implementation also provides an extended reflection API to support inspection and retrieval of our enhanced annotations.
2. From Java to @Java
In this section we describe the Java annotation model and we detail the features that the @Java extension provides. The model that we presented here builds upon the previous work in [12].
Annotations in Java. Almost since its introduction, the Java platform has always supported some form of meta-data to describe internal data structures and to direct the behavior of the virtual machine and of the compiler. For instance, modifiers such as , in Java code, instruct the compiler to treat some values in a special way; similarly, the interfaces Serializable and Clone are often called marker interfaces, because they do not declare any methods and they just tag a class with a specific property.
Listing 2. Java annotations.
Since Java 5, the platform provides a general purpose and customizable annotation mechanism (also known as meta-data facility) that allows the programmer to define and use annotation types. The facility consists of a syntactic mechanism to declare annotations, annotate declarations, APIs to retrieve such annotations, along with an internal binary representation to represent them in class files. Annotations are defined using a special type. The definition of an annotation type is similar to an interface declaration. Listing 2 shows how to create and use an annotation type in Java. Annotations can be markers, single-valued, or multi-valued. Annotation types with no members or that provide default values for all members may be used as marker annotations. Single-valued annotations expect one parameter, multi-valued one or more named parameters.
The Annotation class also provides meta-annotation types that describe properties of a new annotation type, and that are used to actually annotate other annotations. Among the others, @Target specifies which elements of a program can be annotated by the annotation that is being defined, and @Retention instructs the compiler whether the annotation should be made available in the class file, possibly for run-time consumption. The Java core reflection API provides methods to dynamically retrieve annotations that have a run-time retention policy. The classes Method, Field and Class all implement the AnnotatedElement interface that includes methods to access the associated annotations (if any). For instance, isAnnotationPresent(A.class) returns true when @A decorates the target element, and getAnnotations () returns an array of all the annotations decorating a given element. The following code snippet shows how the getAnnotation() API can be used to retrieve the A annotation associated with a given class.
In short, annotations in a Java program play the role of user-defined parameterized keywords, describing properties of a particular piece of code. These properties can be exploited to direct the compilation process, or even describe run-timespecific properties. For instance, in the case of AOP, annotations may be employed to mark specific code sections that need advising.
The main limit in Javas current annotation model is that annotations can only be attached to element declarations—e.g., method and field declarations—but they cannot decorate a specific code section or an expression. Moreover, they can only be resolved statically: it is not possible to assign the return value of a method call, or the value of a field, unless it is defined , and the only allowed values that can be assigned are primitive values, Strings, Classes, enums, annotations, and arrays of the preceding types.
Listing 3. Foo.java
@Java in a nutshell. The @Java language is a natural extension to Java that supports a richer annotation model, where assignment of runtime-computed values is supported, and even blocks and expressions can be annotated. These richer annotation types are defined following the familiar, native Java syntax, with only a few extensions.
In @Java, annotation may hold values of any Java type, and members can be dynamically evaluated; that is, they can refer non-constant values that are only known at runtime. We call annotations that use this feature Dynamically Evaluated Annotations (DEAs). DEAs extend seamlessly the native Java model, without requiring any additional hints to the compiler. The @Java compi
剩余内容已隐藏,支付完成后下载完整资料
外文翻译
学生姓名 |
: |
路宗冈 |
学号 |
: |
20121308114 |
学院名称 |
: |
计算机与软件学院 |
专业名称 |
: |
计算机科学与技术 |
摘要
注解代码的能力一般情况下也就是附带任何元数据到程序中的能力,是编程语言中越来越普遍的特征。
Java注解是能够将自定义的,结构化的元数据附加到类,字段和方法的声明中。然而,这一机制也有一定的限制:注解只能修饰声明而且它们的实例也只能被静态解决。
在这个任务中,我们提出了用更丰富的注解模型扩展到java(名为@Java),它支持代码块注解和表达式注解,也能够动态计算成员变量。换句话说,在我们的模型中,注解的粒度可以延伸到语句和表达式级别,并且注解也能够保存运行时计算的表达式的结果。
2.从java到@java
在本节中,我们描述了Java注解模型并且详细介绍了@Java扩展提供的功能。我们在这里提出的模型依赖于以前的工作,在[12]可以找到相关内容。
Java的注解自推出以来,Java平台一直提供某种形式的元数据来描述内部数据结构并引导虚拟机和编译器的行为。比如,java代码中像transient,volatile这样的修饰符,通知编译器以一种特殊的方式来处理某些值。同样,Serializable和Clone接口通常被称为标记接口,因为它们不声明任何方法并且它们只用一种特定的属性来标注一个类。
我们对java注解模型的扩展有两方面:(一)我们介绍了块和表达式注解,(二)我们允许每个注解都能持有动态计算的值。我们的实现也能够提供扩展的反射API来支持我们的增强注解的检查和检索。
列表2.java注解
自从java5发布以来,该平台就提供了一个通用和定制的注解方式(也称为元数据设施),它允许程序员定义和使用注解类型。该设施由一个语法机制来声明注解,注解声明了APIs获取这样的注解,以及在class文件中用一种内部二进制格式来呈现它们。注解被定义用来使用一种特定的类型,它的类型定义和接口声明类似。表2表示如何在java中创建和使用注解类型。注解可以是一个标记,单值或者多值类型。没有任何成员的注解类型或者所有成员有默认值的标记类型可以被用来标记注解。单值注解期待一个参数,多值注解可以是一个或者多个指定的参数。注解类还提供了描述一个新的注解类型的属性元注解类型, 以及用于实际标注其他注解。在其它注解中,@Target指定哪些程序的元素可以由所定义的注解所标注,@Retention指示编译器是否应该在类文件中提供标注,可能是运行消耗。Java核心反射API提供了一些方法来动态检索具有运行时保留策略注解。类方法中,field和class都实现了AnnotatedElement接口,包括访问相关的注解的方法(如果有的话)。比如,@A修饰目标元素时isAnnotationPresent(A.class)返回true,getAnnotations()返回所有修饰给定元素的注解数组。下面的代码片段显示了getAnnotation()接口如何被用于检索与给定类相关联的一个注解。
总之,Java程序的注解提供用户定义参数的关键字和描述一个特定的代码的性能的作用。这些特性可以被利用来直接编译过程,或者甚至是描述运行中特定的属性。例如,在AOP的例子中,注解可以用于标记需要advise的特定代码段。
在Java中当前注解模型的主要限制是,注解只能附在元素声明,比如方法和字段声明,但他们不能修饰一个特定的代码段或表达式。此外,它们只能静态解决:分配一个方法调用的返回值或字段的值是不可能的,除非它被定义,并且可以被分配唯一的允许值是原始值,字符串,类,枚举,注解,和前面类型的数组。
列表3.Foo.java
@Java简而言之。该@Java语言是自然扩展到Java支持更丰富的注解模型,其中支持的运行时计算的值的分配,甚至块和表达式可以标注。这些更丰富的注解类型的定义于熟悉的,原生的Java语法之下,并且只有少数的扩展。
在@Java,注解可以持有任何Java类型的值,并且成员变量可以动态计算;也就是说,它们可以指向那些只在运行时生成的不是常量的值。我们称使用该功能的动态计算标注(DEAS)为注解。 DEAS无缝地扩展本机Java模型,而不需要任何额外的提示编译器。该@Java编译器检测注解扩展类型的出现(即不属于原产于Java的注解模型类型),它在幕后工作,以尽可能使这些自定义类型的无缝使用。因此,在@Java代码中DEAs外观看上去大多是相同的Java注解;但是,因为它们支持非最终值,DEAS相对于传统的注释,动态在运行时动态计算。列如,清单4展示了@Author将一个Person实例作为它的值。
块和表达式注解是对原生Java注解模型的扩展用来支持细粒度元数据注入代码。块注解(参见清单3)可以用来修饰一个语句或语句序列。从语法上来讲,带注解的块是一个注解前面的Java块(零个或多个声明,括号内封闭的一个序列)。注解块也可以嵌套。注解表达式是已经用括号括起来的Java表达式,并在之前已经注解(参见清单3)。块注解和表达式注解之间的主要区别是,表达式注解的计算出来的是结果(简单地说,它可以被分配给一个变量)。注解表达式也可以嵌套。另一方面,与Java块相比,一个带注解块是零或多个语句的序列组合,而且它不计算为结果,在这个意义上,一个块不能被分配给一个变量。清单4展示了一个注解代码的列子,它既用了块注解(@Trace)也用了传统的DEAs注解方式(@Author)。
清单4.块注解和动态计算的注解的使用例子
2.1. 使用@Java注解
Java 5中通过提供反射API检查方法,类或字段声明来说明注解存在。同样,@Java语言带有一个扩展的反射API检查DEAS,寻找方法里的注解块和表达式。该扩展是为了Java的注解模型中的无缝结合,因此要遵守与原生注解模型(直接或间接)规定的规则。
动态计算的注解。DEAS的介绍引出了一些有趣的问题。比如,DEAS的其中一个问题就是那些注解何时应该被计算。在块注解和表达式注解的情形中,可以是在程序运行过程中对其进行计算。尤其地,我们的选择是通过已执行代码之后的注解内容来评估。在所有其他情况下,DEAS注解声明,就像和他们的本地Java对应。这里的选择是,当他们使用反射检查,只延迟计算出自己的价值。
DEAS可能包含类字段的引用,方法调用和构造函数的结果以及有效的Java表达式。块和表达式注解也允许指向局部变量。由该注解保存的值假定有被传递的价值。例如,清单4的@Trace注解将包含循环体已经被实际执行命中的次数。该信息通过使用反射提取出来一个posteriori。在同一清单中的@author注解修饰了从外部源检索到的关于作者丰富的数据信息的类。DEAS可以使用扩展的API进行检索。在介绍中,我们表明,使用那些满是注解的框架的程序员一个共同的问题是要能够分配更新后的值给他们的注解。这是很容易看到的想法是能够容纳,可以在运行时更新状态的对象实例。我们很容易看到,DEAS可以持有运行时更新的状态对象实例。
清单5.DEAS可扩展反射API使用实例
块和表达式注解。表达式和块注解是Annotation的子类。因为这些注解发生于方法中的主体中,它们可以通过询问的方法对象中检索(即,方法的具体化,反射API返回)。然而,由相同的推理,可发生在构造函数中存在块和表达注解,而且一个字段的表达式初始化也会存在表达式注解。
Method,Constructor和Filed类的实现是通过添加特定的方法来处理标注的表达式(见表1的简短摘要)。比如,getExpressionAnnotations()方法返回所有表达式注解的一个数组。此外,Method和Constructor也包括了块注解相关的方法。比如,如果m是Method的一个实例,那么m.getBlockAnnotations()返回该方法主体中所有块注解的数组。在清单6中,我们可以检索出现在清单3中的每个块注解Block的一个数组。在这个特殊的情况下,只有一种该类型的注解,但是该方法将返回一个数组,因为多次出现在原则上是可能的。
清单6.使用扩展反射API
表1.扩展反射API的一部分
表2.AnnotatedBlock.的API
也有一些方法可以接触到二进制码和注解构造器的源码呈现。比如,getAnnotatedBlocks()返回AnnotatedBlock实例的数组。这个类提供程序员额外的方法来注入注解的代码块。比如,它可以迭代二进制码和源码,并且有一些方法可以描述文件中块开始的偏移量(见表2)。表达式注解也有一些相似的操作(比如getAnnotatedExpressions())。
@Java的反射API不允许程序员在注解的代码中进行进一步的操作,因为它仅限于自省功能,如Java的原生反射库。所谓代求,即,程序的行为的反射改变,可以通过第三方工具的方式来实现,如Javassist进行[13]和BCEL[14]执行的源代码或字节码操作。清单7显示了一个例子。
清单7使用BSEL的代码块
3.实现
@Java字节码是与标准的Java字节码兼容,并且不需要定制的虚拟机来执行。通过这种性能智能化的方式,生成的字节码相当于没有标注的代码;一个小的性能损失可以用DEAS被检测到,但它主要是涉及到动态值的计算,这是可以预料的(想要更详细的,参见第5部分)。通过atjavac工具编译分三个阶段进行。在第一阶段,atjavac从@Java扩展语法到Java兼容中间的表示,表现的就像源到源翻译器。在第二阶段,标准的javac编译器在翻译文件中调用。在第三阶段,atjavac可执行带出@ Java的注解中间表示和自定义的字节码属性替换它们。虽然DEAS正交块和表达式注解,前者的编译过程需要比其他两个多一点的机器,因此我们认为对读者先了解块和表达注解编译过程更容易。所以我们也将继续描述DEAS。
3.1块和表达式注解
在第一阶段@Java块和表达注解被翻译成常规的Java的语法,使得输入文件可以使用javac编译。
清单8.Foo.java(清单3)被atjavac翻译
注解块和表达式的开始和结束都使用了特殊的占位符方法调用标识。这样一来,atjavac甚至在已编译的类文件中就能找到注解块和表达式。它们的字符串参数以一种独特的,易于识别的编译的代码的方式定义。它们对注解块的源代码中的位置信息进行编码比如:内部数字标识符,块开始和结束的行和列,嵌套级别的块注解;最后一部分是块注解的字符串表示。比较特殊的是,块被两个方法调用所包围,而一个表达式仅仅作为一个返回计算后表达式结果的内部方法的参数传递。在这两种情况下,这些方法只充当虚设占位符;它们将在第三阶段。注意在@Java中我们不能注解包含continue和break语句的块,或者其它跳出注解块执行流程的语句;同样,这些语句容纳在一个注解块中,他们的目标也是在块中(一个包围的循环体)。这是因为,注解块被认为是自包含的执行单元。
@Java注解也会转化为虚拟机创建的,空的方法注解:这是需要将验证和编译信息javac进注解字节码中。虚拟方法始终是BA_n_r_c或EA_n_r_c的形式,其中,BA和EA分别代表块和表达注解,n是块或表达注解,R和C的数字标识符是附加说明的块或表达开始的行号和列号。这些方法将在第三阶段中完全剥离出去。注解将被改造成字节码的定制属性。
清单9.Trace.java被atjavac编译
3.2.动态计算的注解
和块注解和表达式注解相似,即使DEAS也必须由它们映射到本地Java构造器进行模拟。在这种情况下,atjavac工具生成用于保存动态值中的协同类。例如,参考清单4。注解持有局部变量的值,并且因此仅在运行时已知。同伴类是自动生成的,它是作为插入包含DEA类的代码中的内部类,它标注了一个特殊的内部元注释(@DEA)。比如,在清单9中@Trace块注解的使用导致了atjavac工具生成了Trace_DEA_0的内部类。该工具使用@DEA注解持有独特的标识符来将一个内部类标记成协同类;比如,在这个情况下,这个独特的标识符是“0
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[29403],资料为PDF文档或Word文档,PDF文档可免费转换为Word
课题毕业论文、外文翻译、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。