对于注解(也被称做元数据),Java 8 主要有两点改进:类型注解和重复注解。

1.类型注解

1)Java 8 的类型注解扩展了注解使用的范围。

在java 8之前,注解只能是在声明的地方所使用,java8开始,注解可以应用在任何地方。

eg:

//创建类实例
new@Interned MyObject();
//类型映射
myString = (@NonNull String) str;
//implements 语句中
class UnmodifiableList<T> implements@Readonly List<@Readonly T> { ... }
//throw exception声明
void monitorTemperature() throws@Critical TemperatureException { ... }

Note:

在Java 8里面,当类型转化甚至分配新对象的时候,都可以在声明变量或者参数的时候使用注解。
Java注解可以支持任意类型。
类型注解只是语法而不是语义,并不会影响java的编译时间,加载时间,以及运行时间,也就是说,编译成class文件的时候并不包含类型注解。

2)新增ElementType.TYPE_USE 和ElementType.TYPE_PARAMETER(在Target上)

新增的两个注释的程序元素类型 ElementType.TYPE_USE 和 ElementType.TYPE_PARAMETER用来描述注解的新场合。
ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中。
ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中(eg:声明语句、泛型和强制转换语句中的类型)。
eg:

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

3)类型注解的作用

类型注解被用来支持在Java的程序中做强类型检查。配合第三方插件工具Checker Framework(注:此插件so easy,这里不介绍了),可以在编译的时候检测出runtime error(eg:UnsupportedOperationException; NumberFormatException;NullPointerException异常等都是runtime error),以提高代码质量。这就是类型注解的作用。

Note:

使用Checker Framework可以找到类型注解出现的地方并检查。

eg:

import checkers.nullness.quals.*;
public class TestDemo{
void sample() {
@NonNull Object my = new Object();
}
}

使用javac编译上面的类:(当然若下载了Checker Framework插件就不需要这么麻烦了)

javac -processor checkers.nullness.NullnessChecker TestDemo.java

上面编译是通过的,但若修改代码:

@NonNull Object my = null;

但若不想使用类型注解检测出来错误,则不需要processor,正常javac TestDemo.java是可以通过编译的,但是运行时会报 NullPointerException 异常。

为了能在编译期间就自动检查出这类异常,可以通过类型注解结合 Checker Framework 提前排查出来错误异常。

注意java 5,6,7版本是不支持注解@NonNull,但checker framework 有个向下兼容的解决方案,就是将类型注解@NonNull 用/**/注释起来。

import checkers.nullness.quals.*;
public class TestDemo{
void sample() {
/*@NonNull*/ Object my = null;
}
}

这样javac编译器就会忽略掉注释块,但用checker framework里面的javac编译器同样能够检测出@NonNull错误。
通过 类型注解 + checker framework 可以在编译时就找到runtime error。

2.重复注解

允许在同一声明类型(类,属性,或方法)上多次使用同一个注解。

Java8以前的版本使用注解有一个限制是相同的注解在同一位置只能使用一次,不能使用多次。

Java 8 引入了重复注解机制,这样相同的注解可以在同一地方使用多次。重复注解机制本身必须用 @Repeatable 注解。

实际上,重复注解不是一个语言上的改变,只是编译器层面的改动,技术层面仍然是一样的。

eg:

1)自定义一个包装类Hints注解用来放置一组具体的Hint注解

@interface MyHints {
Hint[] value();
} @Repeatable(MyHints.class)
@interface Hint {
String value();
}

使用包装类当容器来存多个注解(旧版本方法)

@MyHints({@Hint("hint1"), @Hint("hint2")})
class Person {}

使用多重注解(新方法)

@Hint("hint1")
@Hint("hint2")
class Person {}

2)

public class RepeatingAnnotations {
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Filters {
Filter[] value();
} @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Filters.class)
public @interface Filter {
String value();
}
@Filter("filter1")
@Filter("filter2")
public interface Filterable {
}
public static void main(String[] args) {
for (Filter filter : Filterable.class.getAnnotationsByType(Filter.class)) {
System.out.println(filter.value());
}
}
}

输出结果:

filter1
filter2

分析:

注释Filter被@Repeatable( Filters.class )注释。Filters 只是一个容器,它持有Filter, 编译器尽力向程序员隐藏它的存在。通过这样的方式,Filterable接口可以被Filter注释两次。
另外,反射的API提供一个新方法getAnnotationsByType() 来返回重复注释的类型(注意Filterable.class.getAnnotation( Filters.class )将会返回编译器注入的Filters实例)。

3)java 8之前也有重复使用注解的解决方案,但可读性不好。

[java] view plain copy

public @interface MyAnnotation {
String role();
}

public @interface Annotations {
MyAnnotation[] value();
}

public class RepeatAnnotationUseOldVersion {

@Annotations({@MyAnnotation(role="Admin"),@MyAnnotation(role="Manager")})
public void doSomeThing(){
}
}

Java8的实现方式(由另一个注解来存储重复注解,在使用时候,用存储注解Authorities来扩展重复注解),可读性更强。

[java] view plain copy

@Repeatable(Annotations.class)
public @interface MyAnnotation {
String role();
}

public @interface Annotations {
MyAnnotation[] value();
}

public class RepeatAnnotationUseOldVersion {
@MyAnnotation(role="Admin")
@MyAnnotation(role="Manager")
public void doSomeThing(){
}
}

jdk8的扩展注解的更多相关文章

  1. jdk8环境下,添加重复注解的美好体验

    为了实现业务层缓存,定义了几个注解:@Cache.able.@Cache.put.@Cache.del 分别实现对业务方法的 缓存检测.缓存插入 和 缓存清除. public @interface C ...

  2. Java注解一谈

    阅读目录 1.元注解 2.自定义注解 3.注解处理器 android注解框架解析 我们经常会在java代码里面看到:“@Override”,“@Target”等等样子的东西,这些是什么? 在java里 ...

  3. java注解框架

    我们经常会在java代码里面看到:“@Override”,“@Target”等等样子的东西,这些是什么? 在java里面它们是“注解”. 下面是百度百科的解释:java.lang.annotation ...

  4. Android注解支持(Support Annotations)

    注解支持(Support Annotations) Android support library从19.1版本开始引入了一个新的注解库,它包含很多有用的元注解,你能用它们修饰你的代码,帮助你发现bu ...

  5. 开涛spring3(12.3) - 零配置 之 12.3 注解实现Bean定义

    12.3  注解实现Bean定义 12.3.1  概述 前边介绍的Bean定义全是基于XML方式定义配置元数据,且在[12.2注解实现Bean依赖注入]一节中介绍了通过注解来减少配置数量,但并没有完全 ...

  6. Spring MVC (JDK8+Tomcat8)

    1 Spring MVC概述 Spring MVC是Spring为表现层提供的基于MVC设计理念的优秀的web框架,是目前最主流的MVC框架之一. Spring3.0后全面超越Struts2,成为最优 ...

  7. spring 注解模式 详解

    Spring基于注解实现Bean定义支持如下三种注解: Spring自带的@Component注解及扩展@Repository.@Service.@Controller,如图12-1所示: JSR-2 ...

  8. 从ExtensionLoader理解Dubbo扩展机制

    Dubbo的扩展机制是怎么实现的?最简单的回答就是@SPI. Dubbo的插件化思路来源于Java SPI.   JAVA SPI 机制     SPI的全名为Service Provider Int ...

  9. Android注解支持(Support Annotations) (转)

    原文地址:http://www.flysnow.org/2015/08/13/android-tech-docs-support-annotations.html 注解支持(Support Annot ...

随机推荐

  1. Multiply Strings,字符串相乘

    问题描述:给定两个字符串,返回他们的乘积. public class MultiplyStrings { public String multiply(String num1, String num2 ...

  2. XP_SP3_专业汉化版__x86_cd_x14-80404

    1.镜像文件: zh-hans_windows_xp_professional_with_service_pack_3_x86_cd_x14-80404.iso 来自 msdn itellyou 2. ...

  3. No toolchains found in the NDK toolchains folder for ABI with prefix

    通过Android Studio 的Sdk Manager安装NDK,安装完之后编译失败,报错信息如下: No toolchains found in the NDK toolchains folde ...

  4. viewport简介

    Viewport的用处:手机拥有了浏览器的初期,人们并没有专门为移动设备设计页面,造成的直接结果就是,访问的页面是直接将电脑页面进行缩放,操作起来有诸多不便,viewport就是用来解决这个问题的 1 ...

  5. 如何进行数据库,比如ORACLE,SQL SERVER的逆向工程,将数据库导入到PowerDesigner中

    Oracle的反向工程就是指将Oracle中的数据库,当然也可以是SQL Server中的数据库导入到PD中,这个需要建立一个数据库的链接,然后进行逆向工程的操作. 第一步:建立数据库的链接: Pow ...

  6. listView使用小技巧P66--P76

    1.设置分割线高度和颜色 android:divider="@android:color/darker_gray" android:dividerHeight="10dp ...

  7. LeetCode OJ:Intersection of Two Linked Lists(两个链表的插入)

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  8. LeetCode OJ:Valid Palindrome(验证回文)

    Valid Palindrome Given a string, determine if it is a palindrome, considering only alphanumeric char ...

  9. Android 中Activity,Window和View之间的关系

    转自:http://hi.baidu.com/xiaofanqing/blog/item/8261ac114ab14f64cb80c435.html 我这里根据我个人的理解来讲讲我个人对这3个概念的理 ...

  10. CSS: transitions

    CSS Transitions CSS transitions allows you to change property values smoothly (from one value to ano ...