【Java】Java反射调用可变参数的方法

本文探讨了在Java中如何通过反射调用含有可变参数的方法,参考了一篇相关博客并针对测试中遇到的疑惑进行了阐述。

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

文章目录


在这里插入图片描述

1.概述

因为要Java反射调用可变参数的方法,所以参考了这篇文章:https://www.cnblogs.com/huqingchen/p/5979936.html

但是测试过程中,有一点我不明白,就是反射调用可变参数的方法时,为什么一定要保证传入的参数数组长度为1

然后如下

package com.java.reflect.demo;


public class BaseObject {

    public void getObjectName() {
        System.out.println("BaseObject");
    }
}


package com.java.reflect.demo;

public class SubObject extends BaseObject {
    @Override
    public void getObjectName() {
        System.out.println("SubObject");
    }

    public void getParamsLength(String... params) {
        System.out.println("param's length is:" + params.length);
    }

    public void getParamsLength(String param1, String param2) {
        System.out.println(param1 + "-" + param2);
    }

}

测试类如下

package com.java.reflect.demo;

import org.junit.Assert;
import org.junit.Test;

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

import static org.junit.Assert.*;

public class ReflectToMulityParamsMethosTest {

    private static final String BASE_OBJECT_PATH = "com.java.reflect.demo.BaseObject";
    private static final String SUB_OBJECT_PATH = "com.java.reflect.demo.SubObject";



    /**
     * 测试点:测试反射调用可变参数的方法
     */
    @Test
    public void reflectToMulityParamsMethosTest1() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class sClazz = Class.forName(SUB_OBJECT_PATH);
        Object sObj = sClazz.newInstance();//子类实例


        //2.反射调用可变参数的方法
        Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
        //可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
        String[] strParams = {"a","b","c"};
        Object[] cParams = {strParams};
        changeMethod.invoke(sObj, cParams);
    }


    /**
     * 测试点:
     * 参数为 1
     *
     * 运行如下
     * 0
     * 1
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @Test
    public void reflectToMulityParamsMethosTest2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class sClazz = Class.forName(SUB_OBJECT_PATH);
        Object sObj = sClazz.newInstance();//子类实例


        //2.反射调用可变参数的方法
        Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
        //可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
        String[] strParams = {};
        System.out.println(strParams.length);
        Object[] cParams = {strParams};
        System.out.println(cParams.length);
        changeMethod.invoke(sObj, cParams);
    }


    /**
     * 测试点:这个与上面差了一点点,然后一个报错 一个不报错
     * 这里离的参数个数为0,上面的参数个数为1
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @Test
    public void reflectToMulityParamsMethosTest3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class sClazz = Class.forName(SUB_OBJECT_PATH);
        Object sObj = sClazz.newInstance();//子类实例


        //2.反射调用可变参数的方法
        Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
        //可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
        Object[] cParams = {};
        System.out.println(cParams.length);
        changeMethod.invoke(sObj, cParams);
    }


    /**
     * 测试点:测试反射调用可变参数的方法
     */
    @Test
    public void reflectToMulityParamsMethosTest() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class bClazz = Class.forName(BASE_OBJECT_PATH);
        Class sClazz = Class.forName(SUB_OBJECT_PATH);
        Object bObj = bClazz.newInstance();//父类实例
        Object sObj = sClazz.newInstance();//子类实例
        // 1.反射调用子类父类的重载方法
        // 多态+动态绑定
        Method bMethod = bClazz.getDeclaredMethod("getObjectName");
        bMethod.invoke(bObj);//父类的bMethod调用父类的getObjectName()
        bMethod.invoke(sObj);//父类的bMethod调用子类的getObjectName();
        Method sMethod = sClazz.getDeclaredMethod("getObjectName");
        //不符合多态和动态绑定
        // sMethod.invoke(bObj);//sMethod调用父类的getObjectName(),会报错:java.lang.IllegalArgumentException: object is not an instance of declaring class

        sMethod.invoke(sObj);
        //2.反射调用可变参数的方法
        Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
        //可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
        String[] strParams = {"a","b","c"};
        Object[] cParams = {strParams};
        changeMethod.invoke(sObj, cParams);
        //3.反射调用固定长度参数的方法
        Method unChangeMethod1 = sClazz.getDeclaredMethod("getParamsLength", String.class,String.class);
        unChangeMethod1.invoke(sObj, "Hello","Java");
        //也可以写成这样

        Class[] clazzs = {String.class,String.class};
        Method unChangeMethod2 = sClazz.getDeclaredMethod("getParamsLength", clazzs);
        unChangeMethod2.invoke(sObj, "Hello","Java");
        //下面的这种调用形式也是可以的,不过会报警告
        // String[] params1 = {"Hello","Java"};
        // unChangeMethod1.invoke(sObj, params1);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值