注解与反射

反射

反射允许对成员变量,成员方法和构造方法的信息进行编程访问

利用反射获取class对象的三种方式

1 Class.forName("全类名") 全类名:包名+类名 copy reference

2 类名.class

3 对象.getClass( )

源代码阶段 从.java到.class阶段 用1 //最为常用的

在内存中加载阶段 用2 //一般更多的是当作参数传递

在内存中运行阶段 new一个新对象 用3 //当我们有了这个类的对象时,才可以使用

获取class对象代码实现:

复制代码
public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {

        //第一种
        Class clazz = Class.forName("MyReflect.Student");
        System.out.println(clazz);

        //第二种
        Class<Student> clazz2 = Student.class;
        System.out.println(clazz2);

        //第三种
        Student s = new Student();
        Class<? extends Student> clazz3 = s.getClass();
        System.out.println(clazz3);

        System.out.println(clazz==clazz2);
        System.out.println(clazz2==clazz3);

    }
}


public class Student {
    private String name;
    private int age;

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

    public Student() {
    }

    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;
    }

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

利用反射获取构造方法

通过class对象获取构造方法代码实现:

注意括号里面的写法!!!

打印结果:

利用反射获取成员变量

1 获取class字节码文件的对象

复制代码
Class clazz = Class.forName("myReflect2.Student");

2 获取所有的成员变量

复制代码
Field[] fields = clazz.getDeclaredFields();

3 获取单个的成员变量

复制代码
Field name = clazz.getDeclaredField("name");

4 进而获取成员变量记录的值

5 修改对象里面记录的值

打印结果:

利用反射获取成员方法

1 获取字节码文件对象

2 获取里面所有公共的方法对象(包括父类中所有的公共方法

3 获取里面所有的方法对象(不能获取父类的,但是可以获取本类中私有的方法

4 获取指定的单一方法

()里面不仅要写方法名字,还要写参数类型

5 获取方法抛出的异常

6 方法运行

方法代码:

方法运行代码:

反射的作用

1 获取一个类里面的所有信息,获取到了之后,再执行其他的业务逻辑

2 结合配置文件,动态的创建对象并调用方法

反射练习题

1 保存信息

复制代码
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class ReflectDemo {
    public static void main(String[] args) throws IllegalAccessException, IOException {
        Student s = new Student("小妮子",18);
        Teacher t = new Teacher("Yang",35);
        saveObject(s);
    }
    public static void saveObject(Object obj) throws IllegalAccessException, IOException {
        //获取字节码文件的对象
        Class<?> clazz = obj.getClass();

        //创建IO流
        BufferedWriter bw  = new BufferedWriter(new FileWriter("myreflect\\a.txt"));

        //获取所有的成员变量
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            //获取成员变量的名字
            String name = field.getName();
            //获取obj对象中 成员变量的值
            Object value = field.get(obj);
           bw.write(name+"="+value);
           bw.newLine();     //写一行换一行
        }
        bw.close();
    }
}

Teacher类中有 name salary 构造方法 toString

Student类中有name age 构造方法 toString

2 与配置文件结合,动态的创建对象,并调用方法

复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //读取配置文件中的信息
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream("myreflect\\prop.properties");
        prop.load(fis);
        fis.close();
        System.out.println(prop);

        //获取全类名和方法名
        String className = (String) prop.get("classname");
        String methodName = (String) prop.get("method");

        System.out.println(className);
        System.out.println(methodName);

        //利用反射创建对象并运行方法
        Class<?> clazz = Class.forName(className);
        //获取构造方法
        Constructor<?> con = clazz.getDeclaredConstructor();
        Object o = con.newInstance();   //创建对象
        System.out.println(o);

        //获取成员方法并运行
        Method method = clazz.getDeclaredMethod(methodName);
        method.setAccessible(true);
        method.invoke(o);
    }
}

Student类、Teacher类在上一题的基础上分别加了一个学习,教书方法

注解

作用

本身不是代码的一部分,不会影响代码的执行

在编译、类加载和运行时被读取和处理

为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段

基本语法

注解是使用 @interface 关键字定义的,并且默认继承自 Annotation 接口。

复制代码
public @interface MyAnnotation {
    String value() default "";
    int count();
}

自定义注解

相关推荐
牛奔14 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
寻星探路18 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
lly20240619 小时前
Bootstrap 警告框
开发语言
2601_9491465320 小时前
C语言语音通知接口接入教程:如何使用C语言直接调用语音预警API
c语言·开发语言
曹牧20 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
KYGALYX20 小时前
服务异步通信
开发语言·后端·微服务·ruby
zmzb010320 小时前
C++课后习题训练记录Day98
开发语言·c++
爬山算法21 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty72521 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai