java学习之反射

这篇博客主要介绍了Java中的反射机制,包括Class类的使用、动态加载类的概念、如何获取方法和成员变量信息,以及如何进行反射的基本操作。内容涵盖Class对象的三种获取方式、动态加载类在运行时的优势、Method类和Field类在获取方法和字段信息上的应用,以及通过Constructor获取构造函数信息的方法。通过反射,可以在运行时动态地获取类的信息并进行相关操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Class类

  1. 在面向对象的世界里,万事万物皆对象。
    java语言里,静态的成员、普通数据类型类不是对象。
  2. 类是谁的对象?
    类是对象,类是java.lang.Class类的实例对象。
  3. 如何实例化对象?
  • 使用new创建一个对象
package Test903;

public class Test {
    public static void main(String[] args) {
        //Foo的实例对象如何表示
        Foo foo=new Foo();
    }
}
class Foo{

}
  1. Foo这个类,也是一个实例对象,即Class类的实例对象,如何表示呢?任何一个类都是Class类的实例化对象,三种实例化方式:
  • 第一种:调用Object类中的getClass()方法。
  • 第二种:使用类.class取得,之前是产生了类的实例化对象之后取得的class对象,但是此时并没有取得实例化对象。也就是说,任何一个类都有一个隐含的静态成员变量class。
  • 第三种:调用class类的一个方法Class.forName()
package Test903;

public class Test {
    public static void main(String[] args) {
        //Foo的实例对象如何表示
        Foo foo=new Foo();
        //Foo这个类,也是一个实例对象,即Class类的实例对象,如何表示呢
        //任何一个类都是Class类的实例化对象
        //第一种表达方式:任何一个类都有一个隐含的静态成员变量class
        Class c1=Foo.class;
        //第二种表达方式:已知该类的对象,通过getClass方法
        Class c2=foo.getClass();
        /*c1,c2表示了Foo类的类类型(class type),万事万物皆对象,类也是对象
        * 是class类的实例对象*/
        System.out.println("第一种方式"+c1);
        System.out.println(c1==c2);//true
        //第三种方式:
        Class c3=null;
        try {
            c3=Class.forName("Test903.Foo");
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(c2==c3);//true
        
    }
}
class Foo{

}
  1. 通过类的类类型创建该类的对象实例,即通过c1,c2,c3创建类Foo的实例化对象,实例化对象方法:public T newInstance() throws InstantiationException,IlleagalAccessException
  • 前提要求:需要无参构造方法
  • 程序代码:
package Test903;

public class Test {
    public static void main(String[] args) {
        //Foo的实例对象如何表示
        Foo foo = new Foo();
        //Foo这个类,也是一个实例对象,即Class类的实例对象,如何表示呢
        //任何一个类都是Class类的实例化对象
        //第一种表达方式:任何一个类都有一个隐含的静态成员变量class
        Class c1 = Foo.class;
        //第二种表达方式:已知该类的对象,通过getClass方法
        Class c2 = foo.getClass();
        /*c1,c2表示了Foo类的类类型(class type),万事万物皆对象,类也是对象
         * 是class类的实例对象*/
        System.out.println("第一种方式" + c1);
        System.out.println(c1 == c2);//true
        //第三种方式:
        Class c3 = null;
        try {
            c3 = Class.forName("Test903.Foo");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(c2 == c3);//true
        Foo foo1 = null;
        try {
            foo1 = (Foo) c1.newInstance(); //需要强制类型转换,需要无参构造方法
        } catch (Exception e) {
            e.printStackTrace();
        }
        boolean flag = foo1 instanceof Foo;
        System.out.println("是不是Foo的对象: " + flag);
        foo1.print();
    }
}

class Foo {
    public void print() {
        System.out.println("这个Foo类的print方法");
    }
}

2. 动态加载类

  1. Class.forName("类的全称"),不仅表示了类的类类型,还代表了动态加载类。
  2. 编译时刻加载类是静态加载类,运行时刻加载类是动态加载的。
  • new创建对象是静态加载类,在编译时刻就需要加载所有的可能用到的类
  • Class.forName()动态加载类,在运行时刻加载

3. java获取方法信息

  1. 获取类名称:getName()
  2. 获取类的信息:getClass()
  3. Method类,方法对象,一个成员方法就是一个Method对象。
  • getMethods()方法获取所有public的函数,包括父类继承而来的
  • getDeclaredMethods()获取所有该类自己声明的方法
package Test903;

import java.lang.reflect.Method;

public class Test1 {
    public static void main(String[] args) {
        Class c1=int.class;
        Class c2=String.class;
        Class c3=double.class;
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c1.getClass());
        System.out.println(c1.getName());
        /*
        Method类,方法对象,一个成员方法就是一个Method对象
        getMethods()方法获取所有public的函数,包括父类继承而来的
        getDeclaredMethods()获取所有该类自己声明的方法
         */
        Method[] ms=c2.getMethods();
        //c1.getDeclaredMethods();
        for (int i = 0; i <ms.length ; i++) {
            //得到方法返回值类型的类类型
            Class returnType=ms[i].getReturnType();
            System.out.println(returnType.getName()+" ");
            //得到方法的名称
            System.out.print(ms[i].getName()+"(");
            //获取参数类型,得到参数列表的类型的类类型
            Class[] paramTypes=ms[i].getParameterTypes();
            for (int j = 0; j <paramTypes.length ; j++) {
                System.out.print(paramTypes[j].getName()+",");
            }
            System.out.println(")");
        }
    }
}

4. 获取成员变量、构造函数信息

  1. 成员变量也是对象。
  2. java.lang.reflect.Field Field类封装了关于成员变量的操作。
  • getFileds()方法获取得是所有得public的成员变量的信息
  • getDeclaredFields获取的是该类自己声明的成员变量的信息
package Test903;

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

public class Test1 {
    public static void main(String[] args) {
        Class c1=int.class;
        Class c2=String.class;
        Class c3=double.class;
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c1.getClass());
        System.out.println(c1.getName());
        /*
        成员变量也是对象,java.lang.reflect.Field
        Field类封装了关于成员变量的操作
        getFileds()方法获取得是所有得public的成员变量的信息
        getDeclaredFields获取的是该类自己声明的成员变量的信息
         */
        Field[] fs=c2.getDeclaredFields();//c1.getFields();
        for (Field field:
             fs) {
            //得到成员变量的类型的类类型
            Class fieldType=field.getType();
            String typeName=fieldType.getName();
            //得到成员变量的名称
            String fieldName=field.getName();
            System.out.println(typeName+" "+fieldName);
        }
        }
    }


  1. 构造函数也是对象,java.lang.Constructor中封装了构造函数的信息
  • getConstructors()方法获取得是所有的public的构造函数
  • getDeclaredConstructors()获取的是该类自己声明的构造函数
package Test903;

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

public class Test1 {
    public static void main(String[] args) {
        Class c1=int.class;
        Class c2=String.class;
        Class c3=double.class;
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c1.getClass());
        System.out.println(c1.getName());
        /*
        构造函数也是对象,java.lang.Constructor中封装了构造函数的信息
        getConstructors()方法获取得是所有的public的构造函数
        getDeclaredConstructors()获取的是该类自己声明的构造函数
         */
        Constructor[] cs=c2.getDeclaredConstructors();
        for (int i = 0; i < cs.length; i++) {
            System.out.print(cs[i].getName()+"(");
            Class[] paramTypes=cs[i].getParameterTypes();
            for (int j = 0; j <paramTypes.length ; j++) {
                System.out.print(paramTypes[j].getName()+",");
            }
            System.out.println(")");
        }
        }
    }


5. 反射的基本操作

  1. 如何获取某个方法?

    方法的名称和方法的参数列表才能唯一的确定某个方法

  2. 利用Method类方法,方法反射的操作method.invoke(对象,参数列表)

    方法没有返回值时返回null,有返回值就返回具体的返回值,但返回的是Object对象,需要做类型转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

就是二二二二婷

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

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

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

打赏作者

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

抵扣说明:

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

余额充值