注解与反射

反射

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

利用反射获取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();
}

自定义注解

相关推荐
ULTRA??1 小时前
C语言简化版本开辟动态内存的万能MALLOC宏封装
c语言·开发语言
talenteddriver1 小时前
java: 分页查询(自用笔记)
java·开发语言
enjoy编程1 小时前
Spring-AI 利用KeywordMetadataEnricher & SummaryMetadataEnricher 构建文本智能元数据
java·人工智能·spring
繁华似锦respect1 小时前
lambda表达式中的循环引用问题详解
java·开发语言·c++·单例模式·设计模式·哈希算法·散列表
我要升天!1 小时前
QT -- 网络编程
c语言·开发语言·网络·c++·qt
Unlyrical1 小时前
为什么moduo库要进行线程检查
linux·服务器·开发语言·c++·unix·muduo
GIS阵地1 小时前
Qt实现简易仪表盘
开发语言·c++·qt·pyqt·qgis·qt5·地理信息系统
heartbeat..1 小时前
介绍一下软件开发中常见的几种的架构模式
java·架构·开发