• 反射课后习题及做题记录


    1.    写出获取Class实例的三种常见方式
    
        获取Class类对象(实例)的三种方式
        - 类名.class属性
             Class c1 = Student.class;
        - 对象名.getClass()方法
             Student s = new Student();
             Class c3 = s.getClass();
        - Class.forName(全类名)方法
            Class c4 = Class.forName("com.itheima_02.Student");
            
    2.    谈谈你对Class类的理解
        1.类的加载过程:
        程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。
        接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件
        加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此
        运行时类,就作为Class的一个实例。
        2.换句话说,Class的实例就对应着一个运行时类。
        3.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式
        来获取此运行时类。
    

    反射

          反射就是把Java类中的各种成分映射成相应的java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java类的Class类显示要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。

          一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以的得到这些实例对象

    3. 利用反射和重载完成以下功能
    1)创建Student类,类中有属性name和age并封装属性
    2)重载Student的构造函数,一个是无参构造并,另一个是带两个参数的有参构造,要求在构造函数打印提示信息 
    3)创建带main函数的NewInstanceTest类,利用Class类得到Student对象
    4)通过上述获取的Class对象分别调用Student有参函数和无参函数

         a. 使用对象名.getClass()方法 获取class实例

    打印出来的是存储地址

    代码和 打印结果:

    1. package com.B.Reflect_15.Ask_03;
    2. import java.lang.reflect.Constructor;
    3. import java.lang.reflect.InvocationTargetException;
    4. public class Test {
    5. public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException {
    6. //3)创建带main函数的NewInstanceTest类,利用Class类得到Student对象
    7. // a.-对象名.getClass()方法 获取class实例
    8. Student s1 = new Student();
    9. Classextends Student> c = s1.getClass();
    10. // 此乃提示信息!
    11. //com.B.Reflect_15.Ask_03.Student@6bdf28bb
    12. //----------
    13. //com.B.Reflect_15.Ask_03.Student@6b71769e
    14. //
    15. //进程已结束,退出代码 0
    16. /
    17. // 4)通过上述获取的Class对象分别调用Student有参函数和无参函数
    18. //调用无参函数并创建对象obj
    19. Constructor constructor = c.getConstructor();
    20. Object obj = constructor.newInstance();
    21. //调用带参函数并创建对象obj1
    22. Constructor constructor1 = c.getConstructor(String.class, int.class);
    23. Object obj1 = constructor1.newInstance("知谓忧",22);
    24. System.out.println(obj);
    25. System.out.println("----------");
    26. System.out.println(obj1);
    27. }
    28. }
    1. 此乃提示信息!
    2. com.B.Reflect_15.Ask_03.Student@6bdf28bb
    3. ----------
    4. com.B.Reflect_15.Ask_03.Student@6b71769e
    5. 进程已结束,退出代码 0
      b.- Class.forName(全类名)方法  获取class实例

    打印出来依旧是地址

    1. package com.B.Reflect_15.Ask_03;
    2. import java.lang.reflect.Constructor;
    3. import java.lang.reflect.InvocationTargetException;
    4. public class Test {
    5. public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException {
    6. //3)创建带main函数的NewInstanceTest类,利用Class类得到Student对象
    7. // b.- Class.forName(全类名)方法 获取class实例
    8. Class c1 = Class.forName("com.B.Reflect_15.Ask_03.Student");
    9. // 4)通过上述获取的Class对象分别调用Student有参函数和无参函数
    10. //调用无参函数并创建对象obj
    11. Constructor constructor = c1.getConstructor();
    12. Object obj = constructor.newInstance();
    13. //调用带参函数并创建对象obj1
    14. Constructor constructor1 = c1.getConstructor(String.class, int.class);
    15. Object obj1 = constructor1.newInstance("知谓忧",22);
    16. System.out.println(obj);
    17. System.out.println("----------");
    18. System.out.println(obj1);
    19. }
    20. }
    1. 此乃提示信息!
    2. com.B.Reflect_15.Ask_03.Student@6bdf28bb
    3. ----------
    4. com.B.Reflect_15.Ask_03.Student@6b71769e
    5. 进程已结束,退出代码

    1. 利用通过反射修改私有成员变量

      1. 定义PrivateTest类,有私有name属性,并且属性值为hellokitty,只提供name的getName的公有方法

      2. 创建带有main方法ReflectTest的类,利用Class类得到私有的name属性

      3. 修改私有的name属性值,并调用getName()的方法打印name属性值

     代码:

    1. package com.B.Reflect_15.Ask_01;
    2. //1. 定义PrivateTest类,有私有name属性,并且属性值为hellokitty,只提供name的getName的公有方法
    3. public class PrivateTest {
    4. private String name = "hellokitty";
    5. public PrivateTest() {
    6. }
    7. public PrivateTest(String name) {
    8. this.name = name;
    9. }
    10. public String getName() {
    11. return name;
    12. }
    13. }
    14. package com.B.Reflect_15.Ask_01;
    15. import java.lang.reflect.Field;
    16. import java.lang.reflect.InvocationTargetException;
    17. //2. 创建带有main方法ReflectTest的类,利用Class类得到私有的name属性
    18. public class ReflectTest {
    19. public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
    20. //- Class.forName(全类名)方法 获取class实例对象
    21. Class c = Class.forName("com.B.Reflect_15.Ask_01.PrivateTest");
    22. // 3. 修改私有的name属性值,并调用getName()的方法打印name属性值
    23. //创建运行时类的对象
    24. PrivateTest pri= (PrivateTest) c.newInstance();
    25. //1. getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
    26. Field name = c.getDeclaredField("name");
    27. //2.保证当前属性是可访问的
    28. //暴力反射,适用于私有构造方法/对象
    29. //public void setAccessible(boolean flag):值为true,取消访问检查
    30. name.setAccessible(true);
    31. //3.获取、设置指定对象的此属性值
    32. name.set(pri,"臭小子");
    33. System.out.println(pri.getName());
    34. }
    35. }

    • 2.利用反射和File完成以下功能

      1. 利用Class类的forName方法得到File类

      2. 在控制台打印File类的所有构造器

      3. 通过newInstance的方法创建File对象,并创建D:\mynew.txt文件 */

    报错!

    1. Exception in thread "main" java.lang.NoSuchMethodException: com.B.Reflect_15.Ask_03.Student.(java.lang.String)
    2. at java.base/java.lang.Class.getConstructor0(Class.java:3349)
    3. at java.base/java.lang.Class.getConstructor(Class.java:2151)
    4. at com.B.Reflect_15.Ask_02.FileDemo.main(FileDemo.java:24)

     最后查看资料后发现出错点在

    - Class.forName(全类名)方法  获取class实例对象

    这一步,类名错误,改过来就运行正确了

    1. public java.io.File(java.lang.String,java.lang.String)
    2. public java.io.File(java.io.File,java.lang.String)
    3. private java.io.File(java.lang.String,java.io.File)
    4. private java.io.File(java.lang.String,int)
    5. public java.io.File(java.net.URI)
    6. public java.io.File(java.lang.String)
    7. 进程已结束,退出代码 0

     完整代码:

    1. package com.B.Reflect_15.Ask_02;
    2. import java.io.File;
    3. import java.lang.reflect.Constructor;
    4. import java.lang.reflect.InvocationTargetException;
    5. import java.lang.reflect.Method;
    6. //利用反射和File完成以下功能
    7. // 1. 利用Class类的forName方法得到File类
    8. // 2. 在控制台打印File类的所有构造器
    9. // 3. 通过newInstance的方法创建File对象,并创建D:\mynew.txt文件
    10. public class FileDemo {
    11. public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    12. //- Class.forName(全类名)方法 获取class实例对象
    13. // Class cla = Class.forName("com.B.Reflect_15.Ask_03.Student");
    14. Class cla = Class.forName("java.io.File");
    15. //获取File的所有构造器并输出
    16. Constructor[] con = cla.getDeclaredConstructors();
    17. for (Constructor c : con) {
    18. System.out.println(c);
    19. }
    20. //获取File的一个构造器
    21. Constructor constructor = cla.getConstructor(String.class);
    22. //用上面得到构造器创建File对象
    23. File file = (File) constructor.newInstance("D:\\mynew.txt");
    24. //获取File的createNewFile方法
    25. Method method = cla.getMethod("createNewFile");
    26. //通过createNewFile方法,File对象,完成文件的创建
    27. method.invoke(file);
    28. }
    29. }

  • 相关阅读:
    【数据结构初阶】队列&&队列的面试题
    STM32_3(GPIO)
    FANUC机器人RSR自动运行模式的相关配置和参数设置(图文)
    2023数维杯国际数学建模竞赛C题思路+代码+模型+论文
    优雅的使用String字符串处理各种类型转换
    华为发布:30岁以下员工仅占28% 你信吗?
    Flink PostgreSQL CDC配置和常见问题
    基于Spring Boot垂钓服务系统的设计与实现毕业设计源码071739
    数学建模笔记(十五):多元统计分析及R语言建模(含数据代码注释,均可供运行,高版本无法导入包则使用自编代码计算)
    【算法与数据结构】【字符串篇】【String的常见函数】
  • 原文地址:https://blog.csdn.net/clover_oreo/article/details/126093031