Java反射

目录

一、反射概述

二、获取class类对象的方法

三、通过反射创建并操作类对象

四、反射应用

1.数据库驱动引擎

 2.面向切面编程(AOP)

        


参考:https://blog.csdn.net/weixin_45525272/article/details/125821047

一、反射概述

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

反射原理:jvm加载.class文件时会为每个java类创建一个class对象,class对象会保存类的所有函数、属性等信息,我们只要获取到类的class对象,就可以通过class对象在不知道类的类型的情况下创建类的对象、调用类的函数。

二、获取class类对象的方法

获取Class类对象有三种方式:

        (1)Class.forName(全类名)方法:编译期获取,通过Class的静态函数forName

        (2)类名.class属性:加载字节码阶段获取,加载类名时获取其class属性

        (3)对象名.getClass()方法:运行时获取,通过被创建的对象的getClass方法
        

代码示例如下:

package org.example;

class Student{
};

public class App
{
    public static void main( String[] args ) throws ClassNotFoundException {
        // 1.通过类名获取
        Class clazz1 = Class.forName("org.example.Student");
        System.out.println(clazz1);
        // 2.通过class属性来获取
        Class clazz2 = Student.class;
        System.out.println(clazz2);
        // 3.利用对象的getClass方法来获取class对象
        Student s = new Student();
        Class clazz3 = s.getClass();
        System.out.println(clazz3);
        //同一个类的类对象都相同
        System.out.println(clazz1 == clazz2);
        System.out.println(clazz2 == clazz3);
    }
}

执行结果如下:

class org.example1.Student
class org.example1.Student
class org.example1.Student
true
true

三、通过反射创建并操作类对象

代码示例如下:

package org.example;

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

class Student{
    private Integer id;
    private String name;

    public Student()
    {
        id = 0;
        name = "";
        System.out.println( "Student()");
    }
    public Student(Integer id,String name)
    {
        this.id = id;
        this.name = name;
        System.out.println( "Student(int id,String name)");
    }
    public void test1(String s){
        System.out.println( "public test1("+s+")" + this);
    }
    private void test2(String s){
        System.out.println( "private test2("+s+")" + this);
    }
    public String toString() {
        return "["+id.toString()+","+name.toString()+"]";
    }
};

public class App 
{

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

        //1.通过类名获取Student的类对象
        Class clazz1 = Class.forName("org.example.Student");
        System.out.println(clazz1);
        //创建Student对象,getConstructor:获取构造函数Student(Integer,String),newInstance:调用构造函数Student(1,"gekang1")
        Object obj1 = (Object) clazz1.getConstructor(Integer.class,String.class).newInstance(1,"gekang1");

        //2.知道Student类的情况下通对象调用函数
        if(obj1 instanceof Student)
        {
            Student s1 = (Student) obj1;
            s1.test1("s1");
        }

        //3.修改对象变量(不知道Student类的情况)
        Field f1 = clazz1.getDeclaredField("name");
        //私有变量访问前先临时设置其访问属性
        f1.setAccessible(true);
        //修改私有变量的值
        f1.set(obj1,"gekang2");

        //4.获取并调用公有函数,getDeclaredMethod获取公有函数test1(String)
        Method m1 = clazz1.getDeclaredMethod("test1",String.class);
        //调用函数test1("m1")
        m1.invoke(obj1,"m1");

        //5.获取并调用私有函数test2(String)
        Method m2 = clazz1.getDeclaredMethod("test2",String.class);
        //设置私有函数访问属性
        m2.setAccessible(true);
        //调用私有函数test2("m2")
        m2.invoke(obj1,"m2");
    }
}

执行结果如下:

class org.example.Student
Student(int id,String name)
public test1(s1)[1,gekang1]
public test1(m1)[1,gekang2]
private test2(m2)[1,gekang2]

四、反射应用

1.数据库驱动引擎

代码示例如下:

package org.example;

import java.lang.reflect.InvocationTargetException;
//数据库接口
interface db {
    abstract void connect(String server);
    abstract void execute(String sql);
    abstract void fetchall();
}
//oracle引擎
class oracle implements db {

    @Override
    public void connect(String server) {
        System.out.println("oracle connect:" + server);
    }

    @Override
    public void execute(String sql) {
        System.out.println("oracle execute:" + sql);
    }

    @Override
    public void fetchall() {
        System.out.println("oracle fetchall");
    }
}
//mysql引擎
class mysql implements db{

    @Override
    public void connect(String server) {
        System.out.println("mysql connect:" + server);
    }

    @Override
    public void execute(String sql) {
        System.out.println("mysql execute:" + sql);
    }

    @Override
    public void fetchall() {
        System.out.println("mysql fetchall");
    }
}

public class App 
{
    public static void main( String[] args ) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //可从配置文件读取数据库驱动引擎
        String database = "org.example.mysql";
        //获取数据库驱动引擎类对象
        Class dbClass = Class.forName(database);
        //反射生成数据库引擎对象(用户只需依赖db接口即可,无需以来oracle和mysql类)
        db a = (db)dbClass.getDeclaredConstructor().newInstance();
        //使用数据库引擎对象
        a.connect("127.0.0.1:1000");
        a.execute("select * from dual");
        a.fetchall();
    }
}

执行结果如下:

mysql connect:127.0.0.1:1000
mysql execute:select * from dual
mysql fetchall

 2.面向切面编程(AOP)

面向切面编程底层本质是用了反射,代码示例如下:

package org.example;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface IStudent{

    void test(String name);

    void test2();
}
class Student implements  IStudent{
    @Override
    public void test(String name){
        System.out.println("Stuend test:" + name);
    }
    @Override
    public void test2(){
        System.out.println("Stuend test2");
    }
}
class StudentHandler implements InvocationHandler {
    private final Object target;

    public StudentHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("在调用方法之前执行一些操作:" + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("在调用方法之后执行一些操作:"+ method.getName());
        return result;
    }
}

public class App {
    public static void main(String[] args) {
        //模拟spring boot框架启动时创建Student对象
        Student s1 = new Student();
        //创建Student拦截器
        StudentHandler sh  = new StudentHandler(s1);
        //创建Student代理(实际返回给用户的是该代理对象)
        IStudent s2 = (IStudent)Proxy.newProxyInstance(s1.getClass().getClassLoader(),s1.getClass().getInterfaces(),sh);
        //执行Student成员函数
        s2.test("gekang");
        s2.test2();
    }
}


        

你可能感兴趣的:(java,java反射)