2 fml19920625 fml19920625 于 2016.03.30 10:32 提问

可变参数的使用,求过位路过的指教一下

请问一下红框里的代码是什么意思呢,为什么不能像上面那样直接example2=(Example01) constructor.newInstance(“100”,“200”,“300”)图片说明图片说明图片说明直接example2=(Example01) constructor.newInstance(“100”,“200”,“300”)的话不断打印“在创建对象时抛出异常,下面执行setAccessable"

3个回答

magoo_up
magoo_up   2016.03.30 12:26
已采纳

这个问题要分几步回答:

1,可变参数,java编译器是将可变参数当作数组处理的

    method(String... args) { }

等价于

    method(String[] args){ }

2,Constuctor.newInstance()使用的就是可变参数

    public T newInstance(Object ... initargs)

等同于

    public T newInstance(Object[] initargs)

3,你要定位到的构造函数相当于

    Example01(String[] strings)

而你的代码

    constructor.newInstance(“100”,“200”,“300”)

等同于

    constructor.newInstance(new Object[]{“100”,“200”,“300”})

代表的是找有三个string作为参数的构造函数,因此只能用

    constructor.newInstance(new Object[]{new String[]{“100”,“200”,“300”}})

你理想中希望java能将三个String当作可变参数去匹配,但是除了直接通过方法调用,外部是不能识别可变参数的

magoo_up
magoo_up 回复fml19920625: 使用new Object[]{new String[]{}},new Object[]{}是Constructor.newInstance的参数,而new String[]{}才是构造函数的参数部分。
一年多之前 回复
fml19920625
fml19920625 是不是指直接example01(”100”,“200”,“300”)就可以,但是newInstance()还要再加Object[]才行呢
一年多之前 回复
magoo_up
magoo_up   2016.03.30 17:01

换一个角度讲,可变参数最后编译后的样子是什么样的?一段包含可变参数函数的代码编译成class,最后通过jd-gui反编译.class文件:
源代码:

     public static void main(String[] args) {
        method("1", "2", "3");
    }

    static void method(String... params) {

    }

通过编译后.class文件反编译:

 public static void main(String[] args)
  {
    method(new String[] { "1", "2", "3" });
  }

  static void method(String[] params)
  {
  }

很明显,经过编译器编译后,可变参数回归到了数组模式。
java.lang.reflect.Constructor是java的反射机制的一部分,即读取的是编译后的.class内容。所以不能识别可变参数,必须用相对应的数组方式。

magoo_up
magoo_up 回复fml19920625: yes
一年多之前 回复
fml19920625
fml19920625 回复fml19920625: 确认一下,意思就是new String[] { "1", "2", "3" }向上转型赋值给了Constructor.newInstance的参数new Object[],并没赋值给构造函数是吧
一年多之前 回复
fml19920625
fml19920625 回复magooup: 万分感谢
一年多之前 回复
magoo_up
magoo_up 回复fml19920625: 这两句话你理解一下: // Object[] o = new String[]{"1", "2", "3"}; // System.out.println(Object[].class.isAssignableFrom(String[].class));
一年多之前 回复
magoo_up
magoo_up 回复fml19920625: 因为用new String[]{"1","2","3"}优先匹配成new Object[]{"1,"2","3"},String不就是一个Object吗,所以还是老老实实的写全吧
一年多之前 回复
fml19920625
fml19920625 回复fml19920625: 还有一点,就是用数组的方式的话new String[] { "1", "2", "3" }就可以啊,为什么Object[]{new String[] { "1", "2", "3" }}
一年多之前 回复
fml19920625
fml19920625 基本明白了,谢谢了哈
一年多之前 回复
fml19920625
fml19920625   2016.03.30 14:43

Constuctor.newInstance()使用的就是可变参数

public T newInstance(Object ... initargs)

等同于

public T newInstance(Object[] initargs)什么意思
magoo_up
magoo_up 看我的最新回答
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!