文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java注解和反射,你学会了吗?

2024-11-30 02:48

关注

注解与注释

元注解介绍

创建注解

public @interface [AnnotationName]{}

元注解(描述注解的一种方式)

@Retention 定义注解的生命周期(source、class、runtime)
2.@Documented 文档注解,会被javadoc工具文档化
3.@Inherited 是否让子类继承该注解
4.@Target 描述注解的应用范围,可选内容如下所示:

创建使用注解示例

注解的创建方式:

  1. 配置元注解,由元注解来声明当前注解的作为范围和声明周期。
  2. 注解中如果需要添加信息,可以用以上方式添加。
  3. 注解信息支持java的基本数据结构。

创建注解 @Study

@Target({ElementType.FIELD, ElementType.TYPE}) // 元注解,定义注解的修饰范围,可以设置多个
@Retention(RetentionPolicy.RUNTIME) // 元注解,定义注解的声明周期
public @interface Study { // 注解内容可以设置值,也可以不设置值

    // 其中的属性是支持JAVA的八大属性的 byte、short、int、long、float、double、boolean、char
    // 如果属性为value,那么使用时,赋值可以不写 "value ="

    String name() default "Neco Deng"; // 表示定义了一个name属性,并且设置了默认值为Neco Deng

    String[] mores(); // 表示定义了一个名字为mores的字符串数组属性,并且没有默认值,即该属性需要显示定义
}

使用注解

@Study(mores = {"first", "second"}) // 在类上使用注解,这里必须定义mores, 不然会报错
public class Person {

    private int id;

    @Study(mores = {"first", "second"}) // 在属性上使用注解,这里必须定义mores, 不然会报错
    private String name;

}

反射

反射(Reflection):在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射。

反射的优缺点

常用的反射API

方法名

返回值

参数描述

Class.forName()

获取类的元信息

当前类文件的具体位置

clazz.getClass()

获取类的元信息

clazz.getDeclaredFields()

获取当前类中的所有属性

当前类文件的具体位置

setAccessible(true)

设置当前属性为可见

true或false

getMethods()

获取类所有方法

invoke(obj)

通过反射执行方法

类的元信息

getAnnotation(class)

获取注解

需要获取到额注解的Class

例子

public class ReflectionDemo {


    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException,
            InstantiationException, NoSuchMethodException, InvocationTargetException {
        // 实例1:通过反射获取到Class元信息
        Person person = new Person();
        Class aClass1 = person.getClass(); // 通过getClass获取元信息
        Class aClass2 = Class.forName("com.model.Person"); // 通过forName获取元信息

        // 实例2:通过反射获取类名,包名
        String name = aClass1.getName(); // 全路径类名 > cn.lazyfennec.model.Person
        String simpleName = aClass1.getSimpleName(); // 不包含路径 > Person
        Package aPackage = aClass1.getPackage(); // 包名 > package cn.lazyfennec.model
        System.out.println(name);
        System.out.println(simpleName);
        System.out.println(aPackage);
        System.out.println("===============================");

        // 实例3:获取类属性
        Field[] declaredFields = aClass1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        // 实例4:获取类属性的具体的值
        person.setId(1);
        person.setName("Neco");
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true); // 设置属性可见可访问,处理私有属性无法访问的问题
            System.out.println(declaredField.get(person));
        }

        // 实例4的另一种写法,只是简单的写法,可以进行优化
        Object obj = aClass1.newInstance(); // 实例化一个新的对象, 相当于反射中的实例化
        declaredFields = obj.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            if (declaredField.getName().equals("name")) {
                declaredField.set(obj, "Neco");
            } else {
                declaredField.set(obj, 1);
            }
            System.out.println(declaredField.get(obj));
        }

        // 实例5:反射获取当前类的方法
        Method[] methods = aClass1.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
        Method method = aClass1.getMethod("getString");
        Object invoke = method.invoke(obj);
        System.out.println(invoke);

        // 实例6:反射获得注解
        Study study = aClass1.getAnnotation(Study.class); // 从类中获取注解
        System.out.println(study);
        String[] mores = study.mores();
        String name1 = study.name();
        System.out.println("name: " + name1 + " mores: " + mores);
        // 从方法上获取注解
        methods = aClass1.getDeclaredMethods();
        for (Method method1 : methods) {
            Study annotation = method1.getAnnotation(Study.class);
            if (annotation == null) continue;
            String name2 = annotation.name();
            String[] mores1 = annotation.mores();
            System.out.println("name: " + name2 + " mores: " + mores1);
        }
        // 从属性上获取注解
        declaredFields = aClass1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Study annotation = declaredField.getAnnotation(Study.class);
            if (annotation == null) continue;
            String annotationName = annotation.name();
            String[] annotationMores = annotation.mores();
            System.out.println("name: " + annotationName + " mores: " + annotationMores);
        }
    }
}

参考

https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/index.html

来源:沐雨花飞蝶内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯