栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

注解和反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

注解和反射

前言

 注解:注解的在jdk1.5版本中更新,产生可以提高代码的功能性,因为他有解释功能的作用,之后在学习中我们还可以发现有了注解,我们可以代替很多配置文件,通过运行期间,反射可以动态的绑定数据。

反射:是JAVA一个非常突出的动态相关机制:Reflection,在阅读底层代码时,很多都是用反射来实现的,它可以动态的帮我做一些琐事,而我们可以不关注如何实现,只需要去用就行,比如SpringBoot。

1.反射

JVM得到class对象,再通过class对象反编译得到得到对象的各种信息。

反射是一种程序运行期间的行为

构建Class对象
    Class.forName("包路径+类型");类型.class;对象.getClass()

        //引用数据类型
        Class string1 = String.class;
        Class string2 = Class.forName("java.lang.String");
        Class string3 = "".getClass();
        System.out.println((string1 == string2 && string1 == string3));
        //基本数据类型
        Class int1 = int.class;
        Class integerClass1 = Integer.class;
        //(Class) Class.getPrimitiveClass("int")  缺省 不能直接调用
        Class integerClass2 = Integer.TYPE;
        Class integerClass3 = Class.forName("java.lang.Integer");
        System.out.println(integerClass1);
        System.out.println(integerClass2.toString());
        System.out.println(integerClass3);
        System.out.println(int1);
        //(isInterface() ? "interface " : (isPrimitive() ? "" : "class "))  //判断是不是接口 基本数据类型
        //            + getName();
 通过反射构建对象

1. 通过class对象直接newInstance()     默认调用空构造为对象初始化信息-->不推荐使用

2. 通过构造器 调用newInstance()  构建原有对象

    getConstructor()  类对象所表示的类的指定公共构造函数getConstructors()  类对象所表示的类的所有公共构造函数getDeclaredConstructor()   类对象所表示的类的指定任意构造函数 getDeclaredConstructors()   类对象所表示的类的所有构造函数
        //不推荐使用  因为不知道该类型是否存在无参构造器
        Employee employee = Employee.class.newInstance();
        //获取构造器
        Class employeeClass = Employee.class;
        Constructor[] cons = employeeClass.getConstructors();
        System.out.println(Arrays.toString(cons));

        System.out.println("---------------");
        //获取指定的私有方法
        Constructor con = employeeClass.getDeclaredConstructor(int.class,String.class);
        //因为是私有方法  需要需略访问权限再使用
        con.setAccessible(true);
        Employee emp = con.newInstance(101,"zhangsan");
        System.out.println(emp);
 调用方法

1.获取方法

    getMethod()  类对象所表示的类的指定公共函数getMethods()  类对象所表示的类的所有公共函数getDeclaredMethod()   类对象所表示的类的指定任意函数 getDeclaredMethods() 类对象所表示的类的所有函数

2.调用方法

        invoke(Object obj, Object... args)    在具有指定参数的指定对象上调用此 方法对象表示的基础方法

        //获取所有的公共方法  包括静态
        Method[] methods = employeeClass.getMethods();
        Arrays.stream(methods).forEach(System.out::println);

        //获取指定的方法
        Method method = employeeClass.getDeclaredMethod("testPrivate");
        System.out.println(method);

        method.setAccessible(true);
        //调用方法  无参返回null
        System.out.println(method.invoke(emp));
        //静态方法 存在返回值  可以跟随对象调用|可以跟随类名调用
        for (Method m : methods) {
            if("testStatic".equals(m.getName())){
                //指定通过emp对象调用
                //System.out.println(m.invoke(emp,-1000));
                //null  通过类名调用
                System.out.println(m.invoke(null,-1000));
            }
        }

操作属性

1.获取属性

    getField()  类对象所表示的类的指定公共属性getFields()  类对象所表示的类的所有公共属性getDeclaredField()   类对象所表示的类的指定任意属性 getDeclaredFields() 类对象所表示的类的所有属性

2.获取属性值

        get(Object obj) 返回指定对象上此 字段表示的字段的值

3.设置属性值

        set(Object obj, Object value) 将指定对象参数上此 字段对象表示的字段设置为指定的新值

     //获取所有公共的
     Field[] fileds = cls.getFields();
     System.out.println(Arrays.toString(fileds));
     //根据属性名获取指定的属性
     Field filed = cls.getDeclaredField("name");
     System.out.println(filed);

     //忽略权限
     filed.setAccessible(true);

     filed.set(emp,"lisi");

     System.out.println(filed.get(emp));

 2.注解

注解是jdk1.5的新特性

作用 :

       1.注释,解释的作用

        2.标志检查的作用   @InterfaceFuntion 检查是不是一个函数式接口 也能表明这是一个函数式接口

        3.添加注解的时候可以通过配置传递参数,运行期间可以通过反射获取到配置的数据,程序中进行使用

        4.注解可以存在与Class文件中

        5.注解大量的代替了配置文件的存在

内置注解

@Oveeide 限定重写父类方法

@Deprecated 标记已过时

@SuppressWarnings 抑制警告     @SuppressWarnings("all")  所有画横线的

@FunctionalInterface 函数式接口  

 

 

 元注解

原注解 : 注解注解的注解
     @Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
     @Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有)
     @documented 表示使用该注解的元素应被javadoc或类似工具文档化
     @Inherited 表示一个注解类型会被自动继承。 //子类没有的注解会从父类寻找

 自定义注解

1.通过@interface自定义注解类型
2.自定义的注解类型默认实现java.lang.annotation Annotation接口
3.自定义的注解类型不能显示的继承其他父类,实现其他接口
4.注解类中可以定义注解类型的字段,特数的定义方法,需要字段名后面添加()  --> 修饰符 类型 字段名();
5.如果注解类型中只有一个字段,建议这个字段定义为value,附值的时候可以直接赋值
6.注解类型中的字段的数据类型,只能为一下几种类型:基本数据类型,String,Annotation,枚举类型,或者这几种类型的数组
7.字段的修饰符只能为public|default
8.通过default关键字为字段定义默认值

@Target和@Retention 

 @Target中的属性     ElementType

1.CONSTRUCTOR  描述构造器

2.FIELD:用于描述域

3.LOCAL_VARIABLE:用于描述局部变量

4.METHOD: 用于描述方法 5.PACKAGE: 用于描述包 6. PARAMETER: 用于描述参数 7.TYPE: 用于描述类、接口 ( 包括注解类型 ) 或 enum 声明

@Rentention     RetentionPolicy

1.SOURCE: 在源文件中有效(即源文件保留)

2.CLASS:在class文件中有效(即class保留)在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife)

3.RUNTIME:在运行时有效(即运行时保留)  //注解处理器可以通过反射,获得该注解的属性值,从而处理一些运行时的逻辑处理

class Defined{
    @MyAnnotation(value="zhangsan",j=10)
    String name;
}
@Target(ElementType.FIELD)
//在声明在运行期间  可以进行数值的绑定
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    //value  默认是他  如果不是需要属性=""
    String value();
    int j() default -1;
}

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785239.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号