reflection - Вызов метода с передачей массива

350
21 февраля 2017, 17:15

Имеется класс вот в таком виде. Тоесть написать Foo или Bar с указанием импорта не получится, только так.

Class foo = Class.forName("com.secret.Foo");
Class bar = Class.forName("com.secret.Bar");

Есть метод в классе Foo под именем make. Ему надо передать массив классов Bar. Как такое реализовать?

Если бы можно было использовать эти классы

Bar bar1 = new Bar(1);
Bar bar2 = new Bar(2);
Bar[] bars = {bar1, bar2};
Foo.make(bars);

А как с рефлексией?

UPD

Попытался сделать так

ArrayList<Object> ar = new ArrayList<>();
ar.add(bar1);
ar.add(bar2);
Class foo = Class.forName("com.secret.Foo");
    for(Method m : foo.getMethods()){
    if(m.getName().equals("make")) {
        m.invoke(foo, new Object[]{ar.toArray()});
}
}

Но таким образом я получаю ошибку

java.lang.IllegalArgumentException: method com.secret.Foo.make argument 1 has type com.secret.Bar[], got java.lang.Object[]
Answer 1

Предположим, что класс Bar выглядит так:

package com.secret;
class Bar
{
    protected final int value;
    protected Bar(int value)
    {
        this.value = value;
    }
}

А класс Foo - так:

package com.secret;
class Foo
{
    protected static void make(Bar[] bars)
    {
        for (Bar bar : bars)
        {
            System.out.println("Making bar: " + bar.value);
        }
    }
}

Тогда извне (с учетом модификатора доступа protected у конструктора и метода) сделать это можно так:

package test;
import java.lang.reflect.*;
public class Test
{
    public static void main(String[] args)
    {
        try
        {
            Class foo = Class.forName("com.secret.Foo");
            Class bar = Class.forName("com.secret.Bar");
            Constructor constr = bar.getDeclaredConstructor(int.class);
            constr.setAccessible(true);
            Object bar1 = constr.newInstance(1);
            Object bar2 = constr.newInstance(2);
            Object array = Array.newInstance(bar, 2);
            Array.set(array, 0, bar1);
            Array.set(array, 1, bar2);
            Method method = foo.getDeclaredMethod("make", array.getClass());
            method.setAccessible(true);
            method.invoke(null, new Object[] { array });
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Вывод на экран:

Making bar: 1
Making bar: 2
READ ALSO
Кнопка вверх android

Кнопка вверх android

Есть активность(активность 1), она запускает другую(активность 2), причем передает некие данные влияющие на то что отображает дочерняя активность(активность...

416
Как вывести массив в обратном порядке без использования length

Как вывести массив в обратном порядке без использования length

Создаётся массив целых чиселНужно вывести массив в обратном порядке

634
Нужна библиотека для оплаты в Android

Нужна библиотека для оплаты в Android

Во многих приложениях есть возможность оплачивать деньги через Qiwi, WebMoney, Visa ит

340
Что такое Hazelcats и с чем его едят?

Что такое Hazelcats и с чем его едят?

Добрый деньСижу в проекте где используется Hazelcast

827