注解与反射

发布于 2020-06-23  318 次阅读


 一,注解(Annotation)

java1.5加入Annotation机制,它用来解释数据结构信息,与注释不完全相同,给类添加额外的辅助信息,我们可以通过反射机制实现对元数据的访问

注解作用:

1,对代码做出解释(与注释类似)

2,被编译器识别(面向机器的注释,给机器看)

注解的作用域:包(package),类(class),方法(method),属性(field)

1,内置注解

内置注解:java自己定义的注解

1.1,@override:定义在java.long.overribe包下,表示一个方法声明打算重写另一个方法的声明

1.2,@Deprecated:定义在java.long.deprecated中,此注释表示不鼓励程序员使用这样的元素(方法过期),

1.3,@SuppressWarnings:定义在java.long.SuppressWarnings中,用来抑制警告信息,与一些注解不同,它需要添加参数

all:使用警告消除

unused:抑制没有用过的代码警告

restriction:抑制禁止使用劝阻或禁止引用的警告

……

1.4,@FunctionalInterface:在java.long.FunctiomalInterface包下,判断接口是否为函数式接口

……内置注解还有很多

2,元注解

元注解:描述注解的注解,java定义了4个标准的meta-annotation类型用来提供对其他annotation类型做声明

注解的参数类型:基本类型,枚举类型,数组类型,String类型

元注解主要有四种:

1,@Target:用来描述注解的使用范围(被描述的注解可以在什么地方用),带参数

Target源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Target {
    ElementType[] value();//枚举类型的参数
}

ElementType[] 源码:

public enum ElementType {
    TYPE, //类
    FIELD, //域
    METHOD, //方法
    PARAMETER, //参数
    CONSTRUCTOR, //构造器
    LOCAL_VARIABLE, //局部变量
    ANNOTATION_TYPE, 
    PACKAGE, //包
    TYPE_PARAMETER, //标注类型参数 
    TYPE_USE, //标注任何类型名称
    MODULE;

    private ElementType() {
    }
}

2,@Retention:表示需要在什么级别保存该注释信息,有三种级别,在RetentionPolicy枚举中

Retention源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Retention {
    RetentionPolicy value();
}

RetentionPolicy value源码:

public enum RetentionPolicy {
    SOURCE,
    CLASS,
    RUNTIME;

    private RetentionPolicy() {
    }
}

RetentionPolicy.SOURCE-------------注解将被编译器丢弃
RetentionPolicy.CLASS -------------注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME ---------VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

一般自定义都用runtime

3,@Documented:将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档

4,@Inherited:允许子类继承父类的注解

3,自定义注解

@Target({ElementType.METHOD})//使用范围在方法
@Retention(RetentionPolicy.RUNTIME)//级别为运行时
@Documented  //可以javadoc工具提取成文档
@Inherited //子类可以继承父类的注解
@interface myuser{   //@interface声明定义的是注解
    String[] value();  //参数为String类型
}
class text{
    @myuser({"333"})
    public void c1(){
    }
}

 一,反射(Reflection)

反射机制:在程序运行时能动态获取类的结构数据,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

反射机制也是Java被称为准动态语言的根本

动态语言与静态语言:

动态语言:在代码运行时才做类型检测,在运行期间结构信息可以改变  如:JavaScript,Python

静态语言:在编译期间就进行了类型检测,类结构信息已经固定,运行期间不可改变 如:C++,C#

java根本上来说既非动态语言也非静态语言,从语言根本出发java是静态语言,但java反射机制让他又具备了静态语言的特质,所以java是准动态语言

传统的java运行顺序:

反射:

java反射依赖class类,每一个类都维护了唯一一个class类对象(每一个class对象对应了一个.class文件),通过class对象可以反射到类结构属性,通过class也能够new实例对象,动态的创建对象

class类的对象的三种创建形式:

1,已知类的实例,通过实例点getclass(Object类方法之一)

 public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        w n=new w();
       Class<?> x= n.getClass();
             w cc=(w) x.newInstance();
             cc.h();
    }
}
class w{
    public void h(){
        System.out.println("wql");

    }

2,已知类名,通过类名点class

public static void main(String[] args) throws IllegalAccessException, InstantiationException {
     Class<?> d=w.class;
    }
}
class w{
    public void h(){
        System.out.println("wql");

    }

3,已知全限定性类名,通过forname

public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
     Class.forName("D:/java/src/main/textwq");
    }
}
class w{
    public void h(){
        System.out.println("wql");

    }

 


路漫漫其修远兮,吾将上下而求索