java反射 (复习)

注解

标签,  对代码的一种解释.

元注解

修饰注解, 约束注解, 定义注解的一部分.

@Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
@Target 指定注解放置的位置
@Repeatable 解决一个类上不能标注重复的注解, @Repeatable相当于指向一个容器。
@Inherited 继承的意思,但是它并不是说注解本身可以继承,而是说如果一个父类被 @Inherited 修饰过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了父类的注解。

Java 预置的注解:

@FunctionalInterface 函数式接口注解,这个是 Java 1.8 版本引入的新特性。一个具有一个方法的普通接口。
@SafeVarargs 参数安全类型注解。它是在 Java 1.7 的版本中加入的。 它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。
@SuppressWarnings 阻止警告的意思。
@Override 子类重写父类方法。
@Deprecated 这个元素是用来标记过时的元素。

注解的属性

注解的属性也叫做成员变量。注解只有成员变量,没有成员方法。

注解的成员变量在注解的定义中以“无形参的方法”形式来声明,成员变量的名字-方法名,成员变量的类型-返回值类型。

注解和反射:注解通过反射获取。
1. 首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解。
2. 然后通过 getAnnotation() 方法来获取 Annotation 对象。 或者是 getAnnotations() 方法。

注解到底有什么用?

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。

注解有许多用处,主要如下:
提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
运行时的处理: 某些注解可以在程序运行的时候接受代码的提取
值得注意的是,注解不是代码本身的一部分。

罗永浩还是罗永浩,不会因为某些人对于他“傻x”的评价而改变,标签只是某些人对于其他事物的评价,但是标签不会改变事物本身,标签只是特定人群的手段。所以,注解同样无法改变代码本身,注解只是某些工具的的工具。

package cn.time.annontation;

import java.lang.annotation.*;

public class TestInherited {

    public static void main(String[] args) {
        Annotation[] annotations = B.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }


    @Test
    public class A{

    }

    public class B extends A{

    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface Test{

    }
}
package cn.time.annontation;

import java.lang.annotation.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class TestRepeatable {

    public static void main(String[] args) {
        Human man = new TestRepeatable().new Human();
        Class<?>[] interfaces = man.getClass().getInterfaces();

        Set<Class> set = new HashSet<>();
        set.addAll(Arrays.asList(interfaces));
        set.add(man.getClass());

        set.forEach(c -> {
            Person[] personArr = (Person[]) c.getAnnotationsByType(Person.class);
            for (Person p : personArr) {
                System.out.println(p.role());
            }
        });
    }

    @Person(role = "girl")
    @Person(role = "boy")
//    @Persons({@Person(role="girl"),@Person(role="boy")})
    public class Human{

    }


    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Persons {
        Person[] value();
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Persons.class)
    public @interface Person {
        String role() default "";
    }

}