如何使用用户给出的参数调用静态方法(反射)

时间:2013-11-25 09:02:25

标签: java reflection method-invocation

我创建了一个应用程序,它显示:类的方法,字段和构造函数(由用户输入JTextField)。它将这些方法,字段和构造函数添加到三个单独的JLists中。 我想让用户可以从列表中选择一个metod,然后调用它(只有参数类型为Stringint的那些方法)。

我不知道如何获取信息该方法需要多少参数,然后每个参数(Stringint)的类型以及如何将它们传递给method.invoke(ARGUMENTS)。< / p>

工作代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Zadanie extends JFrame {
    JList<Method> mList;
    JList<Field> fList;
    JList<Constructor> cList;
    DefaultListModel<Method> modelM;
    DefaultListModel<Field> modelF;
    DefaultListModel<Constructor> modelC;
    JTextField txt;
    JButton buttonOK, buttonReset;
    JPanel centerPanel, topPanel, buttonPanel;
    boolean reseted;

    public Zadanie() {
        reseted = true;
    }


    public void createGUI() {
        setSize(800, 600);

        add(topPanel = new JPanel(new BorderLayout()), BorderLayout.NORTH);
        topPanel.add(txt = new JTextField("Person"), BorderLayout.CENTER);
        topPanel.add(buttonPanel = new JPanel(new GridLayout(1, 2)), BorderLayout.EAST);
        buttonPanel.add(buttonOK = new JButton("OK"));
        buttonPanel.add(buttonReset = new JButton("RESET"));
        topPanel.setBorder(new LineBorder(Color.red, 1));
        add(centerPanel = new JPanel(new GridLayout(3, 1)), BorderLayout.CENTER);
        centerPanel.setBorder(new LineBorder(Color.green, 1));

        modelM = new DefaultListModel<Method>();
        modelF = new DefaultListModel<Field>();
        modelC = new DefaultListModel<Constructor>();

        centerPanel.add(new JScrollPane(mList = new JList<Method>(modelM), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
        centerPanel.add(new JScrollPane(fList = new JList<Field>(modelF), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
        centerPanel.add(new JScrollPane(cList = new JList<Constructor>(modelC), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        createListeners();
        setVisible(true);
    }

    private void createListeners() {
        txt.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                buttonOK.doClick();
            }
        });

        buttonOK.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    if (reseted) {//szukanie klasy
                        reseted = false;
                        Class<?> fetchedClass = Class.forName(txt.getText());
                        Method[] methods = fetchedClass.getDeclaredMethods();
                        System.out.println(methods.length);
                        for (Method method : methods) {
                            modelM.addElement(method);

                        }
                        Field[] fields = fetchedClass.getFields();
                        for (Field field : fields) {
                            modelF.addElement(field);
                        }
                        Constructor[] constructors = fetchedClass.getConstructors();
                        for (Constructor constructor : constructors) {
                            modelC.addElement(constructor);
                        }

                    } else {//odpalanie metod

                    }
                } catch (ClassNotFoundException e1) {
                    reseted = true;
                    e1.printStackTrace();
                }
            }
        });

        buttonReset.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                reseted = true;
                modelM.clear();
                modelF.clear();
                modelC.clear();
            }
        });

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Zadanie().createGUI();

            }
        });

    }

}

class Person {
    int age;
    String name;

    public Person(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    public void doSth(){
        System.out.println("Do sth  1");
    }

    public void doSth(int a){
        System.out.println("Do sth 2");
    }

    public void doSth(String s){
        System.out.println("Do sth  3");
    }

    public static void doSthStatic(){
        System.out.println("Do sth static");
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Osoba [age=" + age + ", name=" + name + "]";
    }

    public static void main(String[] args) {
        Person o = new Person(42, "fas");
        System.out.println(o.getClass().getCanonicalName());
    }

}

2 个答案:

答案 0 :(得分:1)

这可能对您有所帮助

public class Sample {
public String appendStrings(String a,String b) {
     return a.concat(b);
 }
}

现在我将使用appendStrings反射来调用Java

public class Test {

public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
   Sample sample=new Sample();
    Method method=Sample.class.getDeclaredMethod("appendStrings", String.class, String.class);
    System.out.println(method.invoke(sample, "Hello", "World"));
}

}

Out put

 HelloWorld

答案 1 :(得分:0)

有apache commons lib,用1行代码完成。

org.apache.commons.lang.reflect.MethodUtils.invokeExactStaticMethod(Class class, String methodName,  Object[] arguments)

调用一个静态方法,其参数类型与对象类型完全匹配。