动态创建对象执行方法

suaxi
2020-11-28 / 0 评论 / 77 阅读 / 正在检测是否收录...

动态创建对象执行方法

1、创建类的对象:调用Class对象的newInstance()方法

  • 类必须有无参构造器
  • 需要构造器的访问权限
    //获得Class对象
    Class c1 = Class.forName("com.sw.reflection.User");

    //构造一个对象
    User user = (User) c1.newInstance(); //本质是调用类的无参构造
    System.out.println(user);

2、在没有无参构造器的情况下,只要在操作的时候明确的调用类中的构造器并将参数传递进去,就可以实例化操作

  • 通过Class类的getDeclaredConstructor(Class ... parameterTypes)取得本类的指定形参类型的构造器
  • 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数
  • 通过Constructor实例化对象
    //获得Class对象
    Class c1 = Class.forName("com.sw.reflection.User");
    
    //通过构造器创建对象
    Constructor constructor = c1.getDeclaredConstructor(int.class, String.class, int.class);
    User user1 = (User) constructor.newInstance(1, "孙笑川", 30);
    System.out.println(user1);

3、调用指定的方法

通过反射调用类中的方法,通过Method类完成

  • 通过Class类的getMethod(String name,parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型
  • 之后使用Object invoke(Object obj,Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息

Object invoke(Object obj,Object[] args)

  • Object对应原方法的返回值,若原方法无返回值,则返回null
  • 若原方法为静态方法,此时形参Object obj可为null
  • 若原方法形参列表为空,则Object[] args为null
  • 若原方法声明为private,则需要在调用invoke方法前,显示调用方法对象的setAccessible(true)方法,关闭程序的安全检查

setAccessible

  • Method和Field、Constructor对象都有setAccessible方法
  • 其作用是启动和禁止访问安全检查的开关
  • 参数值为true时指反射的对象在使用时应该取消Java语言访问检查

    • 提高反射的效率
    • 使原本无法访问的private私有成员也可以访问
  • 参数值为fasle指反射的对象应执行Java语言访问检查(默认值为false)

通过反射调用类中的方法.png

    //获得Class对象
    Class c1 = Class.forName("com.sw.reflection.User");

    //通过反射调用普通方法
    User user2 = (User) c1.newInstance();
    //通过反射获取一个方法
    Method setName = c1.getDeclaredMethod("setName", String.class);
    //invoke  激活
    //.invoke(对象,"值")
    setName.invoke(user2,"孙笑川");
    System.out.println(user2.getName());

整个实例Demo:

package com.sw.reflection;

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

/**
 * @Author suaxi
 * @Date 2020/11/28 14:31
 * 通过反射,动态的创建对象
 */
public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获得Class对象
        Class c1 = Class.forName("com.sw.reflection.User");

        //构造一个对象
        //User user = (User) c1.newInstance(); //本质是调用类的无参构造
        //System.out.println(user);

        //通过构造器创建对象
        //Constructor constructor = c1.getDeclaredConstructor(int.class, String.class, int.class);
        //User user1 = (User) constructor.newInstance(1, "孙笑川", 30);
        //System.out.println(user1);

        //通过反射调用普通方法
        User user2 = (User) c1.newInstance();
        //通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //invoke  激活
        //.invoke(对象,"值")
        setName.invoke(user2,"孙笑川");
        System.out.println(user2.getName());

        //通过反射操作属性
        User user3 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //不能直接操作私有属性,需关掉程序的安全检测,属性/方法.setAccessible(true);
        name.setAccessible(true);
        name.set(user3,"药水哥");
        System.out.println(user3.getName());
    }
}
0

评论 (0)

取消