如何使用反射创建类对象、构造方法、调用方法和属性等

一.反射的概念

1.1什么是反射?

反射就是把Java类中的各种成分映射成一个个的Java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

1.2 反射常用类

  • Class类—可获取类和类的成员信息
  • Field类—可访问类的属性
  • Method类—可调用类的方法
  • Constructor类—可调用类的构造方法

** 1.3 使用反射的基本步骤**

​ 1.导入java.lang.reflect.*

​ 2.获得需要操作的类的Java.lang.Class对象

​ 3.调用Class的方法获取Field、Method等对象

​ 4.使用反射API进行操作(设置属性﹑调用方法)

二.Class类

2.1 Class类是反射机制的起源和入口

  • 每个类都有自己的Class对象
  • 提供了获取类信息的相关方法
  • Class类继承自Object类

2.2 Class类存放类的结构信息

  • 类名
  • 父类﹑接口
  • 方法﹑构造方法﹑属性
  • 注释
    2.3 获取Class类的三种方式
    1.直接类型.class 例如:
 Class<?> clazz1 = Student.class;//括号泛型可以写Student

2.先创建对象,然后用对象引用来创建

 Student student=new Student();
 Class<?> clazz = student.getClass();

3.Class.forName()创建(推荐使用

 Class<?> clazz2 = Class.forName("night.Student");//注意这里需要写入对象全路径名

2.4 获取类的其他结构

Class clazz = Class.forName("java.lang.Object");
Field fields[ ] = clazz.getDeclaredFields();//获取Field 对象 (即类的属性)
Method methods[] = clazz.getDeclaredMethods();//获取Method 对象 (方法)
Constructor constructors[] = clazz.getDeclaredConstructors();//获取Constructor对象 (构造方法)

下面来一段代码 帮助我们更好的理解反射:

public class Demo1 {
    public static void main(String[] args) throws Exception{
        //获取student的类对象(三种方式)
        //方法一
        Student student=new Student();
        Class<?> clazz = student.getClass();
        //方法二
        Class<?> clazz1 = Student.class;
        //方法三
        Class<?> clazz2 = Class.forName("night.Student");

     //获取clazz的带参构造方法
        Constructor<?> constructor = clazz.getConstructor(String.class, int.class, String.class);
        //使用带参构造创建对象
        Object zhangsan = constructor.newInstance("张三", 23, "男");
        //获取一个为无参的方法  Student中的show方法  
        Method show = clazz.getMethod("show");
        //调用  zhangsan对象的show方法   相当于zhangsan.show();的写法
        show.invoke(zhangsan);//姓名张三  年龄23   性别男

       //这个方法是获取clazz本类中所有的私有方法,返回的是一个数组
       //  Method[] declaredMethods = clazz.getDeclaredMethods();

       //获取clazz类中所有的公开方法,包括从父类中集成的方法  返回是一个数组
       //  Method[] declaredMethods = clazz.geMethods();

       //获取本类中私有属性name   参数写属性的名字
        Field name = clazz.getDeclaredField("name");
        //若修改该类属性 必须调用.setAccessible(true)  设置成true  表示将私有修饰符去掉
        name.setAccessible(true);
        
        //这里相当于zhangsan.name="张三";  
        name.set(zhangsan,"张三");
        
        Field age = clazz.getDeclaredField("age");
        age.setAccessible(true);
        age.set(zhangsan,23);
        
        Field sex = clazz.getDeclaredField("sex");
        sex.setAccessible(true);
        sex.set(zhangsan,"女");
        
      //获取zhangsan的age属性   由于前面没有设置泛型因此返回的是Object类型  需要强转
       // Integer age = (Integer) field.get(zhangsan);

     
        System.out.println(zhangsan);
        
        //下面两种输出是一样的
         System.out.println(sex);
        System.out.println(sex.get(zhangsan));

    }
}

这是Student类

public class Student {
    private String name;
    private int age;
    private String sex;

    public Student(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public Student() {
    }
    public void show(){
        System.out.println("姓名"+name+"  年龄"+age+"   性别"+sex);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
 public static void print(){
        System.out.println("这是一个静态方法");
    }
    public String printInfo(){
        return name+" "+age+" "+" "+sex;
    }
}

另外 当类中有静态方法和有带有返回值的方法时候 比如学生类中的 public static void print() 静态方法 在反射的时候 直接调用就行了 里面不用写对象引用 相当于Student.print(); 因为clazz就是Student的类对象嘛

  Method print = clazz.getMethod("print");
  print.invoke(null);

调用有返回值的方法 返回值类型不指定的话为Object类型

Method printInfo = clazz.getMethod("printInfo");
Object value = printInfo.invoke(zhangsan);//相当于  zhangsan.printInfo();
  System.out.println(value);//打印的value值为方法返回的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值