• 简单说明反射和new的区别和反射的使用代码展示


    目录

    1.反射的认识

    2.反射和new的区别

    3.反射的使用代码展示

    4.反射优点和缺点


    1.反射的认识

    反射是Java语言的一种机制,它允许程序在运行时检查和操作类、方法、字段等信息,而不需要提前知道它们的具体定义。通过反射,我们可以在运行时动态地加载类、创建对象、调用方法以及访问和修改字段。

     Java反射提供了以下核心类:

    细说: 

    (1)Class类:代表Java中的类或接口。通过Class类,我们可以获取类的构造函数、方法、字段等信息。

    (2)Constructor类:代表类的构造函数。通过Constructor类,我们可以创建对象。

    (3)Method类:代表类的方法。通过Method类,我们可以调用方法。

    (4)Field类:代表类的字段。通过Field类,我们可以访问和修改字段的值。

      Java 文件被编译后,生成了 .class 文件, JVM 此时就要去解读 .class 文件 , 被编译后的 Java 文件 .class 也被 JVM 解析为 一个对象,这个对象就是 java.lang.Class . 这样当程序在运行时,每个 java 文件就最终变成了 Class 类对象的一个实 例。我们通过Java 的反射机制应用到这个实例,就可以去 获得甚至去添加改变这个类的属性和动作 ,使得这个类成 为一个动态的类。

    2.反射和new的区别

    仅仅在实例化对象上效果无区别,接下来我会列举一些反射和new重要的区别(不阐述底层原理,只区分不同)

    (1)首先new出来的对象我们无法访问其中的私有属性,但是通过反射出来的对象我们可以通过setAccessible()方法来访问其中的私有属性。

    (2)new对象一定要知道类名(在不知道类名的情况下,你怎么去new?),但反射创建对象不需要知道类名也可以。

    (3)new对象属于静态编译,也就是说当代码生成exe文件的时候会将所有模块都编译进去,当你启动这个exe文件的时候,所有模块就会进行一个加载的过程(初始化)

     反射属于动态编译,编译过程中并不会将模块编译进去,这样初始化的时候就会减少负荷,只有在运行过程中,需要哪些模块的时候才进行调用.


    3.反射的使用代码展示

    我们先看看Class类中的相关方法

    (1)常用获得类相关的方法

    (2)常用获得类中属性相关的方法(以下方法返回值为Field相关)

    (3) 获得类中注解相关的方法

    (4)获得类中构造器相关的方法(以下方法返回值为Constructor相关

     (5) 获得类中方法相关的方法(以下方法返回值为Method相关

    在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息

    接下来展示代码需要导入的包:

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


    3.1获得Class对象的三种方式

    student类

    1. class Student {
    2. //私有属性name
    3. private String name = "wang";
    4. //公有属性age
    5. public int age = 18;
    6. //不带参数的构造方法
    7. public Student(){
    8. System.out.println("Student()");
    9. }
    10. private Student(String name,int age) {
    11. this.name = name;
    12. this.age = age;
    13. System.out.println("Student(String,name)");
    14. }
    15. private void eat(){
    16. System.out.println("i am eat");
    17. }
    18. public void sleep(){
    19. System.out.println("i am pig");
    20. }
    21. private void function(String str) {
    22. System.out.println(str);
    23. }
    24. @Override
    25. public String toString() {
    26. return "Student{" +
    27. "name='" + name + '\'' +
    28. ", age=" + age +
    29. '}';
    30. }
    31. }

     Text类

    1. public class Test {
    2. /*
    3. Class对象 只有一个
    4. */
    5. public static void main(String[] args) {
    6. Class c1 = null;
    7. try {
    8. c1 = Class.forName("demo1.Student");
    9. }catch (ClassNotFoundException e) {
    10. e.printStackTrace();
    11. }
    12. Class c2 = Student.class;
    13. Student student = new Student();
    14. Class c3 = student.getClass();
    15. }
    16. }

    说明:

    (1)直接通过 类名 .class 的方式得到 , 该方法最为安全可靠,程序性能更高
    这说明任何一个类都有一个隐含的静态成员变量 class
    (2) 通过 Class 对象的 forName() 静态方法来获取,用的最多,
    但可能抛出 ClassNotFoundException 异常, 注意这里是类的全路径,如果有包需要加包的路径

    思考: 

    提问: 关于Text类
            System.out.println(c1 == c2);
            System.out.println(c1 == c3);

    答案:ture     ture

    因为:Class对象 只有一个 一个类在 JVM 中只会有一个 Class 实例

    接下来我们开始使用反射,我们依旧反射上面的Student类,把反射的逻辑写到另外的类当中进行理解

    以下均为简单操作,故不做过多说明。

    3.2反射机制创建对象

    代码:

    1. public static void reflectNewInstance() {
    2. Class classStudent = null;
    3. try {
    4. classStudent = Class.forName("demo1.Student");
    5. Student student = (Student)classStudent.newInstance();
    6. System.out.println(student);
    7. }catch (ClassNotFoundException e) {
    8. e.printStackTrace();
    9. } catch (InstantiationException e) {
    10. throw new RuntimeException(e);
    11. } catch (IllegalAccessException e) {
    12. throw new RuntimeException(e);
    13. }
    14. }

    通过反射机制调用构造方法实例化java对象

    代码:

    1. public static void reflectPrivateConstructor() {
    2. Class classStudent = null;
    3. try {
    4. classStudent = Class.forName("demo1.Student");
    5. //获得构造方法
    6. Constructor constructor = classStudent.getDeclaredConstructor(String.class,int.class);
    7. constructor.setAccessible(true);
    8. Student student = (Student)constructor.newInstance("xiaoming",15);
    9. System.out.println(student);
    10. }catch (ClassNotFoundException e) {
    11. e.printStackTrace();
    12. } catch (NoSuchMethodException e) {
    13. throw new RuntimeException(e);
    14. } catch (InvocationTargetException e) {
    15. throw new RuntimeException(e);
    16. } catch (InstantiationException e) {
    17. throw new RuntimeException(e);
    18. } catch (IllegalAccessException e) {
    19. throw new RuntimeException(e);
    20. }
    21. }

     小结:

    1. 先获取到这个有参数的构造方法【用ClassgetDeclaredConstructor()方法获取】
    2. 调用构造方法new对象【用Constructor类的newInstance()方法new对象】

    3.3通过反射机制访问一个java对象的属性

    代码:

    1. public static void reflectPrivateField() {
    2. Class classStudent = null;
    3. try {
    4. classStudent = Class.forName("demo1.Student");
    5. Field field = classStudent.getDeclaredField("name");
    6. field.setAccessible(true);
    7. Student student = (Student)classStudent.newInstance();
    8. field.set(student,"caocao");
    9. System.out.println(student);
    10. }catch (ClassNotFoundException e) {
    11. e.printStackTrace();
    12. } catch (NoSuchFieldException e) {
    13. throw new RuntimeException(e);
    14. } catch (InstantiationException e) {
    15. throw new RuntimeException(e);
    16. } catch (IllegalAccessException e) {
    17. throw new RuntimeException(e);
    18. }
    19. }

    3.4通过反射机制调用一个对象的方法

    代码:

    1. public static void reflectPrivateMethod() {
    2. Class classStudent = null;
    3. try {
    4. classStudent = Class.forName("demo1.Student");
    5. Method method = classStudent.getDeclaredMethod("function",String.class);
    6. method.setAccessible(true);
    7. Student student = (Student)classStudent.newInstance();
    8. method.invoke(student,"我是一个反射的参数!");
    9. }catch (ClassNotFoundException e) {
    10. e.printStackTrace();
    11. } catch (NoSuchMethodException e) {
    12. throw new RuntimeException(e);
    13. } catch (InstantiationException e) {
    14. throw new RuntimeException(e);
    15. } catch (IllegalAccessException e) {
    16. throw new RuntimeException(e);
    17. } catch (InvocationTargetException e) {
    18. throw new RuntimeException(e);
    19. }
    20. }

    4.反射优点和缺点

    优点:

    (1)对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法

    (2)增加程序的灵活性和扩展性,降低耦合性,提高自适应能力

    (3)反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

    缺点:

    (1)使用反射会有效率问题。会导致程序效率降低。具体参考这里:反射效率低的原因

    (2)反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 


    以上为我个人的小分享,如有问题,欢迎讨论!!! 

    都看到这了,不如关注一下,给个免费的赞 

  • 相关阅读:
    基于DEM的坡度坡向分析
    JVM 对象的访问方式
    【C++】-c++11的知识点(中)--lambda表达式,可变模板参数以及包装类(bind绑定)
    VR全景打造透明农业后花园,帮助农业走出乡村
    K8S使用开源CEPH作为后端StorageClass
    浙江大学利用 SVM 优化触觉传感器,盲文识别率达 96.12%
    flutter 递归
    Android 性能优化
    CH58X/CH57X/V208的Broadcaster(广播者)例程讲解
    使用Blazor WASM实现可取消的多文件带校验并发分片上传
  • 原文地址:https://blog.csdn.net/WHabc2002/article/details/133976147