zoukankan      html  css  js  c++  java
  • Java基础教程——注解

    注解

    JDK 5开始,Java支持注解。
    注解,Annotation,是一种代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取并执行,而且不改变原有的逻辑。

    注解可以用于:生成文档、编译检查、代码分析。

    基本注解
    @Override 方法重写、方法覆盖
    @Deprecated 已过时
    @SuppressWarnings 压制编译器警告
    @FunctionalInterface Java8新增。Java 8规定,如果接口中只有一个抽象方法,就是函数式接口(类方法和默认方法不限),此注解用来指定“必须是函数式接口”
    @SafeVarargs Java7新增。将不带泛型的对象(如List[])赋给带泛型变量时,会发生堆污染(Heap pollution),此注解用来压制堆污染。
    package ah.annotation;
    import java.util.ArrayList;
    import java.util.List;
    class A {
    	@Deprecated
    	public void info() {
    		System.out.println("Deprecated:info");
    	}
    	public void warnings() {
    		@SuppressWarnings("unused")
    		String s = null;
    		@SuppressWarnings("all")
    		List myList = new ArrayList();
    	}
    	@SafeVarargs
    	public static void faultyMethod(List<String>... listStrArray) {
    		// Java 7新增注解
    		// Varargs:可变参数
    		// 形参【List<String>...】相当于数组,但Java不支持泛型数组,会将其当做List[]处理
    		// 将不带泛型的对象(如List[])赋给带泛型变量时,会发生堆污染(Heap pollution)
    		// 因此泛型可变参数容易导致堆污染
    	}
    }
    @FunctionalInterface
    interface B {
    	// Java 8规定,如果接口中只有一个抽象方法,就是函数式接口(类方法和默认方法不限)
    	// 此注解用来指定“必须是函数式接口”
    	static void m1() {}
    	default void m2() {}
    	// 只一个抽象方法
    	void m3();
    	// 再一个抽象方法就出错: is not a functional interface
    	// void m4();
    }
    public class TestBaseAnnotation {
    	public static void main(String[] args) {
    		new A().info();
    	}
    }
    

    自定义注解

    使用@interface定义注解。

    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;
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    public @interface MyAnnotation {
    	String id();
    	String name() default "A";
    }
    

    注解本质就是接口,接口的属性本质就是抽象方法。

    // 将一个自定义注解反编译(javap MyAnnotation.class)后会得到如此代码
    public interface MyAnnotation extends java.lang.annotation.Annotation {
      public abstract java.lang.String id();
      public abstract java.lang.String name();
    }
    

    元注解:用于描述注解的注解

    @Target:注解能作用的位置

    |--@Target(ElementType.TYPE):作用于类、接口、枚举
    |--@Target(ElementType.METHOD):作用于方法
    |--@Target(ElementType.FIELD):作用于成员变量
    |--@Target(value = { ElementType.TYPE, ElementType.METHOD }):作用于多处

    @Retention:注解被保留的阶段(retention,保留)

    |--@Retention(RetentionPolicy.RUNTIME):保留到运行时。
    |--|--自定义注解一般都取此值。注解信息会保留到class文件中,可以通过反射获取注解信息。

    @Documented:注解是否被抽取到API文档中

    @Inherited:被注解的类如果有子类的话,注解会被继承

    注解的属性

    (1)注解的属性以无参数方法的形式声明;
    (2)返回值只能是:基本类型、字符串、枚举、注解,或其数组{数组赋值时用大括号,如果就一个值,大括号可以省略}。
    (3)可以指定默认值;
    (4)如果只有一个属性value,则可以直接赋值
    |--|--如:@SuppressWarnings("all")

    package ah.annotation;
    import java.lang.annotation.*;
    //枚举类型
    enum MyEnum {
    	e1, e2;
    }
    // ========================
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation2 {
    	// 属性的返回值
    	int prop1();
    	String prop2();
    	MyEnum prop3();
    	Override prop4();
    	// =============
    	int[] prop11();
    	String[] prop12();
    	MyEnum[] prop13();
    	Override[] prop14();
    }
    // ========================
    // 测试各种赋值操作用的注解
    @interface MyAnn0 {
    	// 无属性的注解(如@Override)
    }
    @interface MyAnn1 {
    	int prop();// 单属性的注解
    }
    @interface MyAnn2 {
    	// 多属性的注解
    	int prop1();
    	int prop2();
    }
    @interface MyAnn_default {
    	// 默认值
    	int prop() default 1;
    }
    @interface MyAnn_value {
    	// 特殊属性value,如果仅1个属性,且叫value,赋值时可省略属性名
    	int value();
    }
    @interface MyAnn_type {
    	String s();
    	MyEnum e();
    	Override a();
    	int[] arr();
    	int[] arr2();
    }
    // ========================
    // 用于注解的类
    class UseAnno {
    	@MyAnn0
    	void m1() {}
    	@MyAnn1(prop = 1)
    	void m2() {}
    	@MyAnn2(prop1 = 1, prop2 = 2)
    	void m3() {}
    	@MyAnn_default
    	void m4() {}
    	@MyAnn_value(1)
    	void m5() {}
    	@MyAnn_type(s = "A", e = MyEnum.e1, a = @Override, arr = { 1, 2 }, arr2 = 3)
    	void m6() {}
    }
    
  • 相关阅读:
    [Leetcode]847. Shortest Path Visiting All Nodes(BFS|DP)
    [Lintcode]Word Squares(DFS|字符串)
    [Lintcode]Inorder Successor in Binary Search Tree(DFS)
    xampp搭建discuz论坛
    Codeforces Round #459 (Div. 2):D. MADMAX(记忆化搜索+博弈论)
    网址备份
    java并发系列
    java创建多线程
    (转)深入理解Java内存模型之系列篇
    (转)Java并发编程:线程池的使用
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11182851.html
Copyright © 2011-2022 走看看