Java 8的类型注解:工具和机会

在以前的Java版本中,开发者只能将注解(Annotation)写在声明中。对于Java 8,注解可以写在使用类型的任何地方,例如声明、泛型和强制类型转换等语句:

@Encrypted String data;
List<@NonNull String> strings;
myGraph = (@Immutable Graph) tmpGraph;

乍一看,类型注解并不是Java新版本最炫的特性。事实上,注解只是语法!工具决定了注解的的语义(即,它们的含义和行为)。本文介绍新的注解语法和实用工具,以提高生产力和构建更高质量的软件。

在金融行业,我们的市场波动和监管环境决定了上市时间比以往任何时候都更加重要。但牺牲安全性或质量绝对不是一个可选项:简单的百分点和基点混乱就可能造成严重后果。这种情况同样存在于所有其它行业。

作为一名Java程序员,也许你已经采用注解来提高软件质量。想想早在Java 1.5中引入的@Override注解。在具有复杂继承层次结构的大型项目中,要跟踪系统运行时会执行方法的哪一种实现是很困难的。如果你不小心修改了某个方法的声明,可能会导致子类方法没有被调用。这种方式取消了一个方法调用,将会引入缺陷或者安全漏洞。为此,Java引入了@Override注解,开发者可以用它来说明该方法覆盖了父类方法。如果程序没有匹配这种意图,Java编译器将使用这些注解来警告开发者。如此,注解扮演了机器检查文档的形式。

开发者可以通过元编程(Metaprogramming)等技术提高生产率,注解在其中扮演了核心角色。其思想是通过注解够告诉工具如何生成新代码、转换代码或者决定运行期的行为。以Java Persistence API(JPA)为例,这也是Java 1.5引入的功能。它允许开发者以声明的方式如@Entity,指定Java对象与数据库实体之间的关系。然后Hibernate这类工具就可以使用这些注解,在运行期生成映射文件和SQL查询。

在JPA和Hibernate的场景中,注解用于支持DRY(Don't Repeat Yourself)原则。有趣的是,无论你在哪寻找支持最佳实践的开发工具,都不难发现注解的存在。一些著名的例子包括使用依赖注入(Dependency Injection)降低耦合,使用面向切面编程(Aspect Oriented Programming)分离关注点。

问题来了:如果注解已经被用于提升质量和提高生产率,为什么我们还需要类型注解?

这个问题的简单回答是:类型注解提供更多的功能。它们帮助自动检测更多的缺陷,为你提供生产力工具的更多控制。

类型注解的语法

在Java 8中,类型注解可以写在使用类型的任何地方,以下是一些例子:

@Encrypted String data
List<@NonNull String> strings
MyGraph = (@Immutable Graph) tmpGraph;

引入一个新的类型注解非常简单,只要定义一个注解,并且其target为ElementType.TYPE_PARAMETERElementType.TYPE_USE,或者两个都包含:

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
public @interface Encrypted { }

ElementType.TYPE_PARAMETER表示注解能写在类型变量的声明语句中(如:class MyClass {...})。而ElementType.TYPE_USE表示注解能写在使用类型的任何语句中(例如声明语句、泛型和强制转换语句中的类型)。

一旦源码中的类型有了注解,就像声明中的注解一样,它可以同时存在于类文件中并在运行时可以通过反射获取(定义注解时使用RetentionPolicy.CLASSRetentionPolicy.RUNTIME策略)。类型注解与以前的注解有两个主要区别:首先,局域变量声明中的类型注解也可以保留在类文件中;其次,完整泛型被保留,并且在运行期可以访问。

尽管注解可以保存在类文件中,但它不影响程序的常规运行。例如,开发人员可能在方法体中声明了两个File变量和一个Connection变量:

File file = ...;
@Encrypted File encryptedFile = ...;
@Open Connection connection = ...;

当程序运行时,传递其中任何一个文件给connection的send(...)方法,都会调用同一个方法实现。

// 以下代码将调用同一个方法
connection.send(file);
connection.send(encryptedFile);

正如你预期的那样,运行期没有区别,也就是说,尽管参数的类型是有注解的,但方法不会基于注解的类型进行重载:

public class Connection{
     void send(@Encrypted File file) { ... }
     // Impossible:
     // void send( File file) { ... }
     . . .
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 注解
, 方法
, 类型
, 语句
, 开发者
, 注解实体类
, 使用注解
, tomcaturlwebsocket注解404
, 注解全局变量
, sql servermybatis注解
, 注解hibernate基类jpa字段
, java注解
Java 注解 override
java官网、java教程、java下载、java7、java jdk,以便于您获取更多的相关知识。

时间: 2024-10-06 08:50:42

Java 8的类型注解:工具和机会的相关文章

Java核心技术点之注解

一.什么是注解 我们大家都知道Java代码中使用注释是为了向以后阅读这份代码的人解释说明一些事情,注解是注释的升级版,它可以向编译器.虚拟机等解释说明一些事情.比如我们非常熟悉的@Override就是一种元注解,它的作用是告诉编译器它所注解的方法是重写父类的方法,这样编译器就会去检查父类是否存在这个方法,以及这个方法的签名与父类是否相同. 也就是说,注解是描述Java代码的代码,它能够被编译器解析,注解处理工具在运行时也能够解析注解.我们在Java源文件中使用注释,是为了以后我们或他人再来读这段

JavaScript静态类型检查工具FLOW简介_基础知识

Flow是Facebook出品的,针对JavaScript的静态类型检查工具.其代码托管在github之上,并遵守BSD开源协议. 关于Flow 它可以帮助我们捕获JavaScript开发中的常见错误,而不需要额外地修改你原有的代码,比如静态类型转换,空值引用等问题. 同时,Flow为JavaScript添加了静态类型的语法标识,这样开发者便可以明确代码中的类型,让其自动地被Flow所维护. 目前,Flow具有以下两特性: 1. Flow的类型检查具有可选性 除非你明确告诉Flow需要对某些文件

数据库-java中的流属于工具类吗,还是属于一种数据类型?

问题描述 java中的流属于工具类吗,还是属于一种数据类型? 数据库存储的blob类型数据不应该是一串二进制数吗,为什么都说它是二进制流. 解决方案 工具类都在这个java.util中定义, 你看包就知道了 流是专门处理Io的. 有一套对应的类来支持它 数据库存储的blob类型数据不应该是一串二进制数吗,为什么都说它是二进制流 存储的数据是二进制数,但是这个二进制数的格式是某个对象的 这就是流对象. 你要通过流对象读出二进制数啊 这和你用流读取一个二进制文件是一样的 解决方案二: 流是一种抽象类

JAVA必须使用类型的外层实例来分配限定?

问题描述 JAVA必须使用类型的外层实例来分配限定? package test; public class Simple { public static void main(String[] args) { int[]arry={3,56,46,33,112,32,48,45,21,88,64,32,7,88,64}; arrysort as= new arrysort(); arry=as.sort(arry); for(int i=0;i<arry.length;i++) { System.

Java的double类型探索.

一.double类型的存储表示 Java的浮点类型表示完全按照IEEE754标准(Standards of IEEE 754 floating point numbers),有兴趣可以上IEEE标准网站(www.ieee.org)查阅.该标准的内容基本上描述了浮点类型的存储格式(Storage Layout),下面我从中总结几段,来概括该标准,详细信息请查阅标准原文. 1.什么是浮点数. 计算机上表达实数有两中方法:定点表示(fixed-point)和浮点表示(floating-point).定

hibernate中java.util.Date类型映射

在Hibernate中对于java.util.Date类型的映射为: java类型 Hibernate类型 Mysql类型 java.util.Date.java.sql.Date date DATE java.util.Date.java.sql.Time time TIME java.util.Date.java.sql.Timestamp timestamp TIMESTAMP 如果使用timestamp作为Date类型映射时,具体代码如下: Java代码 public class Use

最适合Java开发者的大数据工具和框架

文章讲的是最适合Java开发者的大数据工具和框架,当今编程人员面对的最大挑战就是复杂性,硬件越来越复杂,OS越来越复杂,编程语言和API越来越复杂,我们构建的应用也越来越复杂.根据外媒的一项调查报告,以下列出了Java程序员在过去12个月内一直使用的一些工具或框架,或许会对你有意义. 先来看看大数据的概念.根据维基百科,大数据是庞大或复杂的数据集的广义术语,因此传统的数据处理程序不足以支持如此庞大的体量. 在许多情况下,使用SQL数据库存储/检索数据都是很好的选择.而现如今的很多情况下,它都不再

深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)

写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能.本文将深入分析枚举的源码,看一看枚举是怎么实现的,是如何保证线程安全的,以及为什么用枚举实现的单例是最佳方式. 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和class一样,只是一个关键字,他并不是一个类,那么枚举是由

java,用string类型进行十进制加法计算

问题描述 java,用string类型进行十进制加法计算 这是n1,n2长度相同的时候的算法,求改进长度不同的时候又要进位时候的编写方法.如1998+2=2000. 我java初学,请多多指教. private String addNumericStrings(String n1, String n2) { String result=new String(""); String A=new String(""); int v1=0; char ch3=n1.cha