注解与反射java

1.java的注解操作知识

我们使用了@interface声明了AgeAnnotation 注解,并使用@Target注解传入ElementType.FIELD参数来标明@AgeAnnotation 只能用于类上,@Retention(RetentionPolicy.RUNTIME)则用来表示该注解生存期是运行时,从代码上看注解的定义很像接口的定义,确实如此,毕竟在编译后也会生成AgeAnnotation .class文件。对于@Target和@Retention是由Java提供的元注解,所谓元注解就是标记其他注解的注解,下面分别介绍

@Target 指定被其修饰的注解能用于修饰哪些程序元素,成员变量value为ElementType 枚举类型,取值范围:

  1. ElementType.CONSTRUCTOR:用于描述构造器
  2. ElementType.FIELD:用于描述域
    3. ElementType.LOCAL_VARIABLE:用于描述局部变量
    4. ElementType.METHOD:用于描述方法
    5. ElementType.PACKAGE:用于描述包
    6. ElementType.PARAMETER:用于描述参数
    7. ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention指定该注解可使用反射读取,成员变量value:RetentionPolicy 枚举类型,取值范围:

  1. RetentionPolicy.SOURCE:在源文件中有效(即源文件保留)
  2. RetentionPolicy.CLASS:在class文件中有效(即class保留)
  3. RetentionPolicy.RUNTIME:在运行时有效(即运行时保留)

@Documented
指定被其修饰的注解将被JavaDoc工具提取成文档
@Inherited
指定被其修饰的注解将具有继承性

2.自定义注解:

package com.xmx;

import java.lang.annotation.*;

/**
 * @Auther: 郑兴源
 * @DateTime :  2021-11-29 上午 09:25
 * @descriptoin:自定义注解
 */
@Target(ElementType.FIELD)//作用在属性上
@Retention(RetentionPolicy.RUNTIME)// 运行时有效

public @interface AgeAnnotation {
    int value() default 18;//默认值:18
}

3类

package com.xmx;

/**
 * @Auther: 郑兴源
 * @DateTime :  2021-11-29 上午 09:25
 * @descriptoin:学生类
 */

public class Student {
    public String name;

     // @AgeAnnotation(value = 22)//自己 修改默认值 为22
    @AgeAnnotation    //跟随默认值 18
    public int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
   public void show() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

4.操作测试

package com.xmx;

import java.lang.reflect.Field;

/**
 * @Auther: 郑兴源
 * @DateTime :  2021-11-29 上午 09:34
 * @descriptoin:测试类
 */

public class TestStudent {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {

        //反射创建一个student 类型的对象
        Class c = Class.forName("com.xmx.Student");//全路径
        //取对象的某个属性
        Field filed = c.getField("age");

        //判断属性上是否标记了ageAnnotation
        if (filed.isAnnotationPresent(AgeAnnotation.class)) {
            //获取到属性上的注解对象
            AgeAnnotation age = filed.getAnnotation(AgeAnnotation.class);
            //输出注解测对象的值
            System.out.println(age.value());
        }
    }
}

5.结果1
在这里插入图片描述
6.结果2
在这里插入图片描述
8.反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象与方法.
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

package com.xmx.fanShe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Auther: 郑兴源
 * @DateTime :  2021-11-29 上午 10:40
 * @descriptoin:
 */

public class TestMain {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

        //反射来创建对象
        Class c2 = Class.forName("com.xmx.fanShe.Student");//全路径
        //自动调用无参函数
        Object obj1 = c2.newInstance();
        System.out.println("无参->" + obj1);

        //构造器来创建对象
        //通过构造器获取有参构造方法
        Constructor cons = c2.getConstructor(new Class[]{String.class, int.class});//数据类型
        Object obj2 = cons.newInstance("伍银锋", 22);
        System.out.println("有参->" + obj2);

        //操作对象的属性与方法

        Method m = c2.getMethod("show");//方法
        m.invoke(obj2);//执行方法

       Field f = c2.getDeclaredField("age");
        //权限打开--對象的属性  private  public不需要开启权限
        f.setAccessible(true);
        //属性赋值
        f.set(obj2, 99);
        m.invoke(obj2);//执行方法
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值