Annotation

Annotation是一个接口,可以把Annotation当成一个修饰符

Annotation的定义

注解通过@interface定义

public @interface TestAnnotation {
  //Annotation的成员变量通过无形参的方法形式声明,方法名和返回值表示成员变量的名字和类型
  String name();
  //默认值通过default指定
  int age() default 32;
}

提取Annotation的信息

提取Annotation的信息需要用到java.lang.reflect的反射API,并且在定义Annotation的@Retention要指定为RetentionPolicy.RUNTIME

5个基本的Annotation

@Override->强制重写父类的方法,避免出现父类方法名和子类方法名不一致的错误

@Deprecated->标记方法已过时

@Suppress Warnings->取消编译器的警告

@Safe Varages->解决“堆污染”

 public static void main(String[] args) {
List list = new ArrayList();
list.add(20);
//当把一个不带泛型的对象赋值给一个带泛型的变量,引发的错误叫“堆污染”,发生ClassCastException
List<String> ls = list;
System.out.println(ls.get(0));
}

@FunctionalInterface->标记接口是一个函数式接口

@FunctionalInterface
//函数式接口中有一个抽象方法,多个静态方法和默认方法,如果试图声明第二个抽象方法,会报错
public interface Test {
void a();
default void b(){
System.out.println("b");
}
static void c() {
System.out.println("c");
}
}

6个Meta Annotation

@Retention

Retention用于修饰Annotation,作用是指定修饰的Annotation可以保留多长时间

//Retention有一个RetentionPolicy的成员变量value
// value的取值:RetentionPolicy.RUNTIME,RetentionPolicy.CLASS,RetentionPolicy.SOURCE
//RUNTIME、CLASS会将Annotation记录在class文件中,SOURCE会直接丢弃Annotation
//RUNTIME可以通过反射获取Annotation的信息,class不可以
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}

@Target

Target用于修饰Annotation,作用是指定Annotation可以修饰那些程序单元

  • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  • ElementType.CONSTRUCTOR 可以给构造方法进行注解
  • ElementType.FIELD 可以给属性进行注解
  • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
  • ElementType.METHOD 可以给方法进行注解
  • ElementType.PACKAGE 可以给一个包进行注解
  • ElementType.PARAMETER 可以给一个方法内的参数进行注解
  • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
//Retention有一个ElementType的成员变量value
@Target(ElementType.FIELD)
public @interface Test {
}
class A{
@Test
private int a;
}

@Documented

Documented用于修饰Annotation,作用是指定被Documented修饰的Annotation类会被javadoc提取成文档

@Inherited

Inherited用于修饰Annotation,作用是指定被修饰的Annotation具有继承性

@Inherited
//注意这要写上RUNTIME,不然下边的isAnnotationPresent()不能通过反射拿到Annotation信息
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
} @Test
class A{
}
//B类并未使用@Test注解,但是B类也被@Test修饰了
class B extends A{
public static void main(String[] args){
System.out.println(B.class.isAnnotationPresent(Test.class));
}
}

@Repeatable

Repeatable用于修饰Annotation,可以使用多个相同名字的注解

//在没有使用Repeatable前,我们要给某个程序元素注解多个相同名字的注解时,必须要有一个容器注解
@Retention(RetentionPolicy.RUNTIME)
public @interface Result{
String name();
int age();
}
@Retention(RetentionPolicy.RUNTIME)
@interface Results{
Result[] value();
}
@Results({@Result(name="张三",age=16),
@Result(name="李四",age=20)}
)
class Person{
public static void main(String[] args){
Class<Person> pClass = Person.class;
Results results = pClass.getDeclaredAnnotation(Results.class);
System.out.println(results);
}
}
//使用Repeatable注解修改
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Results.class)
public @interface Result{
String name();
int age();
}
@Retention(RetentionPolicy.RUNTIME)
@interface Results{
Result[] value();
}
@Result(name="张三",age=16)
@Result(name="李四",age=20)
class Person{
public static void main(String[] args){
Class<Person> pClass = Person.class;
Results results = pClass.getDeclaredAnnotation(Results.class);
System.out.println(results);
}
}

实际上任然需要容器注解,只是红色的部分写法发生了变化

ElemType

Java 8 中 ElementType 增加了 ElementType.TYPE_USE 和 ElementType.TYPE_PARAMETER。它们都可以限制哪个类型可以进行注解。能在局部变量、泛型类、父类和接口的实现处使用,甚至能在方法上声明异常的地方使用。

ElementType.TYPE_PARAMETER(Type parameter declaration) 用来标注类型参数。

@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface TypeParameterAnnotation { } // 如下是该注解的使用例子
public class TypeParameterClass<@TypeParameterAnnotation T> {
public <@TypeParameterAnnotation U> T foo(T t) {
return null;
}
}

ElementType.TYPE_USE(Use of a type) 能标注任何类型名称,包括上面这个(ElementType.TYPE_PARAMETER的)

ublic class TestTypeUse {

    @Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TypeUseAnnotation { } public static @TypeUseAnnotation class TypeUseClass<@TypeUseAnnotation T> extends @TypeUseAnnotation Object {
public void foo(@TypeUseAnnotation T t) throws @TypeUseAnnotation Exception { }
} // 如下注解的使用都是合法的
@SuppressWarnings({ "rawtypes", "unused", "resource" })
public static void main(String[] args) throws Exception {
TypeUseClass<@TypeUseAnnotation String> typeUseClass = new @TypeUseAnnotation TypeUseClass<>();
typeUseClass.foo("");
List<@TypeUseAnnotation Comparable> list1 = new ArrayList<>();
List<? extends Comparable> list2 = new ArrayList<@TypeUseAnnotation Comparable>();
@TypeUseAnnotation String text = (@TypeUseAnnotation String)new Object();
java.util. @TypeUseAnnotation Scanner console = new java.util.@TypeUseAnnotation Scanner(System.in);
}
}

JavaSE笔记-注释的更多相关文章

  1. JAVASE笔记回顾

    第一部分,JAVA基础和面向对象 part01 入门与开发环境搭建 1: 计算机基础知识(了解)(1)计算机(2)计算机硬件(3)计算机软件系统软件:windows,linux,mac应用软件:QQ, ...

  2. c++语言的学习笔记代码与笔记注释《函数部分》

    具体的笔记以注释的形式写在代码内,每个知识点用函数的形式表现. #include <iostream>; #include<cmath> const double PI=3.1 ...

  3. javaSE 笔记一

    java 环境变量配置 步骤:   右键[计算机]图标 –>[属性]–>[高级系统设置]–>[环境变量]   在"系统变量"里找到"Path" ...

  4. Python核心编程笔记----注释

    python 中注释有两种 第一种,文档注释 第二种,一般的注释 下面是例子: class MyClass: '这个是文档注释' def __repr__(self): return "re ...

  5. QTP自动化测试-笔记 注释、大小写

    1 rem 注释内容 2 ' 注释内容 3 快捷键注释-选择代码行-ctrl+M 4 ctrl+shift+同- 取消注释 大小写 qtp:对小写敏感:如果 变量.sheet页是用小写字母命名,则使用 ...

  6. c++语言的学习笔记代码与笔记注释《面向对象部分》

    #include <iostream> /*这是C++中关于面向对象部分的具体笔记和代码 */ //定义类的语法形式; //类中的成员项目之间相互引用,直接使用成员; //类外引用成员的时 ...

  7. 【Python】2.11学习笔记 注释,print,input,数据类型,标识符

    前面学了好多内存什么的知识,没什么用(我有眼不识泰山233 吐槽一句,这课简直就是讲给完全的编程小白听得 就从语言开始写吧(其实好多已经看过了,再来一遍 话说我已经忘了\(Markdown\)怎么写了 ...

  8. JavaSE笔记-泛型

    定义带泛型的类 public class Cat<T> { //可以用T定义实例变量 private T name; //可以用T定义形参 //构造器没有<> public C ...

  9. JavaSE笔记-异常

    Java 异常 Throwable类的体系结构(一些常用的) 异常分类 checked,unchecked 区分:RuntimeException及其子类,Error类及其子类,是unchecked ...

随机推荐

  1. P1744 采购特价商品 题解(讲解图论)

    图论的超级初级题目(模板题) 最短路径的模板题 图是啥?(白纸上的符号?) 对于一个拥有n个顶点的无向连通图,它的边数一定多于n-1条.若从中选择n-1条边,使得无向图仍然连通,则由n个顶点及这 n- ...

  2. P5239 回忆京都(洛谷3月月赛T2)

    题目描述 射命丸文在取材中发现了一个好玩的东西,叫做组合数. 组合数的定义如下:从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合.所有组合的数量,就是组合数 ...

  3. python错误和调试

    在程序运行过程中,总会遇到各种各样的错误. 有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修复的. 有的错误是用户输入造成的,比如让用 ...

  4. Linux内存管理 (8)malloc

    专题:Linux内存管理专题 关键词:malloc.brk.VMA.VM_LOCK.normal page.special page. 每章问答: malloc()函数是C函数库封装的一个核心函数,对 ...

  5. .Net Core应用框架Util介绍(五)

    上篇简要介绍了Util在Angular Ts方面的封装情况,本文介绍Angular封装的另一个部分,即Html的封装. 标准组件与业务组件 对于管理后台这样的表单系统,你通常会使用Angular Ma ...

  6. 基于 WebGL 的 HTML5 楼宇自控 3D 可视化监控

    前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...

  7. AttributeError: Got AttributeError when attempting to get a value for field `password2` on serializer ` UserSerializer`...

    Error_msg: AttributeError: Got AttributeError when attempting to get a value for field `password2` o ...

  8. 使用axios post 提交数据,后台获取不到

    https://www.cnblogs.com/yiyi17/p/9409249.html(copy https://www.cnblogs.com/loveyaxin/p/8385694.html( ...

  9. Lodop打印表格带页头页尾 高度是否包含页头页尾

    通过设置TableHeightScope,可以实现对ADD_PRINT_TABLE,表格带页头页尾,查看本博客另一篇博文:Lodop打印表格带页头页尾 自动分页每页显示头尾 超文本超过打印项高度,会自 ...

  10. 如何在源码里修改openwrt root密码

    root密码在etc/shadow文件里,但里边的密码是加密过后的.具体的加密方式我不清楚,应该是Linux里的一套加密算法.但要达到修改源码密码的目的,我还是想到了一个间接的办法.首先在源码里改成t ...