反射Class

本文详细介绍了如何在Java中使用反射机制来操作类、构造方法、方法及字段等内容,包括通过不同方式获取Class对象、利用构造方法创建实例、获取并调用方法、获取字段等关键步骤。

一.创建此 Class

1. 通过类的名字来得到

Class<?> c1 = Class.forName("_1Class.Person");

System.out.println(c1);

2. 根据对象来得到类对象

 Person p1 = new Person("张三",18);
 Class<?> c2 = p1.getClass();
 System.out.println(c2);

 3. 根据类来得到

 Class<?> c3 = Person.class;
 System.out.println(c3);

二.使用类对象来创建对象

Person p2 = null;
        try {
            p2 = (Person)c1.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

三.得到构造方法

    1. 得到类对象的公开的构造方法
  

     Constructor[] cons1 = c1.getConstructors();

     for(int i=0;i<cons1.length;i++)
        {
            System.out.println(cons1[i].toGenericString());
        }

    2.得到类对象的所有的构造方法   

        Constructor[] cons2 = c1.getDeclaredConstructors();
        System.out.println("所有方法:");
        for(int i=0;i<cons2.length;i++)
        {
            System.out.println(cons2[i].toGenericString());
        }

  3. 得到指定的构造方法
      

        Constructor con1 = c1.getConstructor(new Class[]{});
        System.out.println("无参数的构造方法:"+con1);
        Constructor con2 = c1.getConstructor(new Class[]{String.class,int.class});
        System.out.println("有参数的构造方法:"+con2);
        Constructor con3 = c1.getDeclaredConstructor(new Class[]{String.class});
        System.out.println("有参数的构造方法:"+con3);

 4. 没有权限的方法,要访问,得设置accessible为true
      

 con3.setAccessible(true);

 5. 使用的到的构造方法来创建对象
        

        Person p1 = (Person)con1.newInstance();
        Person p2 = (Person)con2.newInstance("小明",18);
        Person p3 = (Person)con3.newInstance("大明");

四.获得Methd方法

      1. 得到该类对象上的所有方法信息(还含有父类继承来的方法)
      

        Method[] methods1 = c1.getMethods();
        System.out.println("所有公开的方法:");
        for (int i = 0; i < methods1.length; i++) {
            System.out.println(methods1[i].toGenericString());
        }

       2. 得到该类对象上的自身所有方法信息(含私有方法)
        

        Method[] methods2 = c1.getDeclaredMethods();
        System.out.println("自身所有方法:");
        for (int i = 0; i < methods2.length; i++) 
        {
            System.out.println(methods2[i].toGenericString());
        }


        
        3. 得到具体某个方法
        3.1 得到无参数方法
      

        Method m1 = c1.getMethod("work", new Class[]{});
        System.out.println("无参public work方法:"+m1);


        3.2 得到有参数方法        
      

        Method m2 = c1.getMethod("work", new Class[]{String.class});
        System.out.println("有参public work方法:"+m2);


        33 得到无参数私有方法        
        

        Method m3 = c1.getDeclaredMethod("sleep", new Class[]{});
        System.out.println("无参的私有方法:"+m3);


        
        
        3.4 使用放射方法来调用
        

        Person p1 = new Person("张三",18);
        Person p2 = new Person("李四",18);
        
        m1.invoke(p1,null);// => p1.work()
        m1.invoke(p2,null);// => p2.work()
        m2.invoke(p1,"java代码");//=> p1.work码"("java代)
        m2.invoke(p2,"c++代码");// => p2.work("c++代码")
        
        m3.setAccessible(true);
        m3.invoke(p1,null);
        m3.invoke(p2,null);


        
        // 静态方法        
        

        Method m4 = c1.getMethod("show", new Class[]{});
        m4.invoke(null, null);// Person.show();

五.获得Field字段

       1. 得到公开的字段
        

        Field[] fields1 = c1.getFields();
        System.out.println("公开:");
        for(int i=0;i<fields1.length;i++)
        {
            System.out.println(fields1[i].toGenericString());
        }


        
        2. 得到所有的字段
        

        System.out.println("所有:");
        Field[] fields2 = c1.getDeclaredFields();
        for(int i=0;i<fields2.length;i++)
        {
            System.out.println(fields2[i].toGenericString());
        }
        


        4. 得到某个字段对象
      

        Field f1 = c1.getField("name");
        Field f2 = c1.getDeclaredField("age");
        f2.setAccessible(true);


        
        5. 反射机制修改某个对象的字段的值
        

        Person p1 =new Person("张三",18);
        Person p2 =new Person("李四",19);


        
        // 反射机制设置对象的值
      

        f1.set(p1, "张三丰");// p1.name = "张三丰"
        f2.set(p2, 20);// p2.age = 20


        
        // 反射机制获取对象的值 
        

        System.out.println(f1.get(p1));// p1.getName()
        System.out.println(f2.get(p1));// p2.getAge()

 

Java 反射中,`Class.forName()` 方法主要完成以下工作: - **加载类的 `.class` 文件到 JVM 中**:`Class.forName()` 会将指定类的 `.class` 文件加载到 Java 虚拟机(JVM)中,使得 JVM 能够识别和使用该类。这是类加载过程的一部分,它会在内存中创建该类的 `Class` 对象,这个对象包含了该类的所有信息,如类的结构、方法、字段等。 - **对类进行初始化**:默认情况下,`Class.forName()` 除了加载类的 `.class` 文件外,还会对类进行初始化操作,即执行类中的静态代码块(`static` 块)。静态代码块是在类被加载时自动执行的代码,通常用于对类的静态变量进行初始化或执行一些一次性的初始化操作。例如,在手写 JDBC 的驱动加载时,一般选用 `Class.forName()` 方法,因为 JDBC 驱动的加载代码通常放在静态代码块中,使用 `Class.forName()` 可以确保驱动被正确加载和初始化[^3]。 `Class.forName()` 方法有多个重载版本,其中 `Class.forName(String className)` 是最常用的版本,它会默认对类进行初始化。而 `Class.forName(String name, boolean initialize, ClassLoader loader)` 带参函数可以通过 `initialize` 参数控制是否对类进行初始化,`true` 表示要初始化,`false` 表示不初始化,即不执行静态代码块。例如: ```java try { // 加载并初始化类 Class.forName("com.example.MyClass"); // 加载类但不初始化 ClassLoader loader = ClassLoader.getSystemClassLoader(); Class.forName("com.example.MyClass", false, loader); } catch (ClassNotFoundException e) { e.printStackTrace(); } ``` 只有调用了 `newInstance()` 方法才会调用构造函数,创建类的对象。不过,`newInstance()` 方法在 Java 9 及以后已被弃用,推荐使用 `Constructor.newInstance()` 方法来创建对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_无往而不胜_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值