反射技术学习笔记

反射技术学习笔记

为什么要学习反射?

经常听到的答案:

为了可以操作私有变量,操作私有方法

大伙可以思考,这有什么意义?

其实,我更认为这是反射机制带来一个副作用而已,而不是目的

思考题

目标:实现一个导弹发射平台,输入具体的导弹类型,就发送不同的导弹

要求:可以修改配置文件,但不允许修改代码

即编译期无法确定要执行的类和对象,只有到运行期才能确定

1.什么是反射

Java的反射机制让Java语言具有动态性

Java的反射机制实现程序运行期间,动态获取类的信息以及动态调用对象方法的功能;

2.反射技术的核心

Student student = new Student();

当执行上面这段程序时,JVM会在方法区创建Student类对应的Class对象,这个对象包含了完整的类结构

信息;

Class类就是反射的核心,是一个特殊的类,用来描述所有类的结构信息,我们来查看Class的类结构,

加深理解
类结构 ,包名、类名、成员变量、成员方法、构造方法、接口

3.获取Class对象的三种方式

1,通过getClass()方法

Student student = new Student();
Class studentClass = student.getClass();

2,通过.class静态属性

Class studentClass = Student.class;

3,通过Class.forName()方法

//性能较比前两种较差
//优点是灵活性高
Class studentClass = Class.forName("com.pojo.Student");
//Class.forName(xxx.xx.xx)返回的是一个类。
//Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。

4.获取构造方法

1,获取类定义的构造方法

package reflection;

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

/**
 * @author XiaoAI
 * @date 2023/7/20 16:06
 */
public class ConstructorTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Book> bookClass = Book.class;
		//1.获取public修饰的构造方法
        java.lang.reflect.Constructor<?>[] constructors = bookClass.getConstructors();
        for (java.lang.reflect.Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }

        System.out.println("-------------------------------------------");
        //2.获取所有的构造方法
        Constructor<?>[] declaredConstructors = bookClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        Constructor<Book> constructor = bookClass.getConstructor(String.class, double.class);
        Book book = constructor.newInstance("Java编程思想", 9999);
        System.out.println(book.toString());
    }
}

2,通过构造方法创建对象

//1.获取到构造器对象
Constructor<Book> constructor = bookClass.getConstructor(String.class, double.class);
//2.通过构造器对象的newInstance()方法创建对象
Book book = constructor.newInstance("Java编程思想", 9999);
System.out.println(book.toString());

5.获取类方法

1,获取方法

package reflection;

import java.lang.reflect.Method;

/**
 * @author XiaoAI
 * @date 2023/7/20 16:30
 * 通过反射技术获取方法
 */
public class MethodTest {
    public static void main(String[] args) {
        Class<Book> bookClass = Book.class;
        //1.获取所有public修饰的方法
        Method[] methods = bookClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("------------------------------------");
        //2.获取所有方法
        Method[] declaredMethods = bookClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
    }
}

2,调用方法

package reflection;

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

/**
 * @author XiaoAI
 * @date 2023/7/20 16:33
 * 通过反射技术调用方法
 */
public class MethodTest2 {
    public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //1.获取类对应的Class对象
        Class<Book> bookClass = Book.class;
        //2.通过Class对象,获取到其内部具体定义的方法
        Method test = bookClass.getDeclaredMethod("test", null);
        //3.通过Class对象构造具体类的实例
        Book book = bookClass.newInstance();
        //4.通过反射执行方法调用
        //私用方法需要开放访问权限
        test.setAccessible(true);
        test.invoke(book, null);

    }
}

6.获取类的成员变量

1,获取成员变量

package reflection;
import java.lang.reflect.Field;

/**
 * @author XiaoAI
 * @date 2023/7/21 15:24
 * 通过反射技术获取类属性
 */
public class FieldTest {
    public static void main(String[] args) {
        //1.获取某个类的Class对象
        Class<Book> bookClass = Book.class;
        //2.通过Class对象获取属性
        Field[] fields = bookClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("------------------------------------");
        Field[] declaredFields = bookClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

    }
}

2,操作成员变量

package reflection;

import java.lang.reflect.Field;

/**
 * @author XiaoAI
 * @date 2023/7/21 15:24
 * 通过反射技术来动态给某个属性赋值
 */
public class FieldTest2 {
    public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException {
        //1.获取某个类的Class对象
        Class<Book> bookClass = Book.class;
        //2.通过Class对象获取属性
        Field otherField = bookClass.getField("other");
        //3.通过Class的对象来创建类的实例
        Book book = bookClass.newInstance();
        //4.调用成员变量对象的set方法实现赋值
        otherField.set(book, "反射技术演练");
        System.out.println(book.other);
    }
}

7.获取类的其他信息

//1.获取包名
clazz.getPackage();       
//2.获取类名
clazz.getName();
//3.获取父类
clazz.getSuperclass();
//4.获取该类实现的接口信息
clazz.getInterfaces();
//5.获取注解信息
clazz.getAnnotations();

8.反射的效率

1,反射性能测试

2,提高反射性能,关闭安全检查

//设置为true,表示关闭安全检查
//设置为false,表示执行Java语言的访问检查
setAccessible(true);
//但是整体的性能表现依然不如直接调用
//但是要注意,反射解决的是实现动态功能的问题
package reflection;

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

/**
 * @author XiaoAI
 * @date 2023/7/21 16:14
 * 反射性能测试
 */
public class Reflection {
    public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        long start = System.currentTimeMillis();
        Book book = new Book();
//       //14
//        for (int i = 0; i < 100000000; i++) {
//            book.test1();
//        }

        Class<Book> bookClass = Book.class;
        Method test1 = bookClass.getMethod("test1", null);
        Book book1 = bookClass.newInstance();
        //239 124
        test1.setAccessible(true);
        for (int i = 0; i < 100000000; i++) {
            test1.invoke(book1, null);

        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值