【类反射】类的调用(调用类中的成员:成员变量、方法、构造方法)

★ 构造类对象

使用构造器新建对象。根据指定的参数类型找到相应的构造函数,传入相应参数调用执行,以创建一个新的对象实例。

代码演示:

package cn.hncu.reflect.test;

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

import org.junit.Test;

/**
 * 
 * 利用类反射访问(调用)构造器、方法、属性
 * 
 *@author <a"283505495@qq.com">lxd</a>
 *@version 1.0 2017-4-19 下午6:29:50
 *@fileName ReflectOperateObj.java
 */
public class ReflectOperateObj {
     /*
      * 1、通过类反射调用构造器
     */
    @Test
    public void constructorDemo() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
        Class c=Class.forName("cn.hncu.reflect.test.UserModel2");

        //1.1调用空参构造器
        Object obj=c.newInstance();//创建此Class的对象所表示的类的一个实例
        System.out.println("1:"+obj.toString());

        //1.2调用指定(非空参)参数类型类表构造器
        //类似于:UserModel2 user=new UserModel2("Jack",23);
        //1.2.1要先获取对应构造器对象con
        Class[] parameterTypes=new Class[2];//★1:构造形参数列表★
        parameterTypes[0]=String.class;//★2:参数列表中的第一个参数为String.class★
        parameterTypes[1]=int.class;//★3:参数列表中的第二个参数为int.class★
        //Class parameterTypes = null;可变参数是一个参数
        Constructor con=c.getDeclaredConstructor(parameterTypes);//★4:得到构造器对象con★ 参数列表为:可变参数 Class... parameterTypes

        //1.2.2 通过con对象进行构造新对象
        Object[] initargs=new Object[2];//★6:构造实参列表★
        initargs[0]=new String("Jack");
        initargs[1]=new Integer(23);
        Object obj2=con.newInstance(initargs);//★5:调用newInstance(Object... initargs)★
        System.out.println("2:"+obj2);

    }

★ 调用方法

根据方法名称执行方法。根据方法名与参数类型匹配指定的方法,传入相应参数与对象进行调用执行。若是静态方法,则不需传入具体对象。

代码演示:

    /*
     * 2、通过类反射调用普通方法
     */
    @Test
    public void methodDemo() throws Exception{
        Class c=Class.forName("cn.hncu.reflect.test.UserModel2");

        //2.1调用空参方法,类似于user.toString();
        //★1★先获取指定方法所对应的Method对象
        Method m=c.getDeclaredMethod("toString", null);//name - 方法名 :parameterTypes - 参数数组 
        //★2★执行方法---调用该method的invoke方法,同时把user以实参形式传入
        Object user=c.newInstance();//也可以用demo1的非空参构造器new对象
        //UserModel2 user=new UserModel2("Jack", 23);可以方便测试
        Object str=m.invoke(user, null);//★3★得到的实际方法 <=>String str=user.toString();
        System.out.println("1:"+str);

        //2.2调用有参数方法 如:sum(int , double)---user.sum(100,12.13)
        //调用方式和无参类似
        //★2★构造形参
        Class[] parameterTypes=new Class[2];
        parameterTypes[0]=int.class;
        parameterTypes[1]=double.class;
        //★1★获取对象
        Method m2=c.getDeclaredMethod("sum", parameterTypes);
        //★3★之行方法调用实参
        Object resObj=m2.invoke(c.newInstance(), new Object[]{23,100.12} );//obj - 从中调用底层方法的对象      args - 用于方法调用的参数 
        System.out.println("2:"+resObj);

        //2.3调用静态方法
        Method m3=c.getDeclaredMethod("abc", null);
        m3.invoke(c.newInstance(), null);//void
    }

★ 获取与设置属性值

根据属性名称读取与修改属性的值,访问非静态属性需传入对象为参数。

代码演示:

    /*
     * 3、通过类反射调用属性(成员变量)
     */
    @Test
    public void fieldDemo() throws Exception{
        Class c=Class.forName("cn.hncu.reflect.test.UserModel2");
        //3.1 访问静态变量
        Field fld=c.getField("MAX");
        fld.set(null, 222);//给静态变量设置值
        Object v1=fld.get(null);//读取静态变量中的值
        System.out.println("1:"+v1);

        //3.2 访问非静态变量---可以使用get(),也可以使用基本数据类型专用的get方法 如getDouble()
        Field fld2=c.getField("value");
        Object v2=fld2.get(c.newInstance());//这种get方法可以不需要知道其数据类型是什么
        System.out.println("v2:"+v2);

    }

暴力访问所有成员:

代码演示:

    /*
     * 4、暴力访问
     */
    @Test
    public void violenceDemo() throws Exception{
        Class c=Class.forName("cn.hncu.reflect.test.UserModel2");
        Method m=c.getDeclaredMethod("psum", new Class[]{int.class,double.class,float.class});
        m.setAccessible(true);//打开暴力访问门 该方法是AccessibleObject类中的,后者是Field、Method、Constructor的共同父类,因此都可以采用这一句打开暴力访问开关。
        Object resStr=m.invoke(c.newInstance(), new Object[]{23,2.1,12f});
        System.out.println(resStr);

    }

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值