gpt4 book ai didi

java.reflection.Method.invoke(...) 不重新转换参数

转载 作者:太空宇宙 更新时间:2023-11-04 15:08:37 24 4
gpt4 key购买 nike

我正在尝试 Java Reflection API。我只是将任何给定类的 Method 对象提取到 JComboBox 中,并在其 itemSelected 上为参数(当然还有调用对象)创建一个接口(interface)。

这工作正常,没有发布。

但是在 invokeButton 的操作中,我尝试使用给定的参数调用所选方法。

最初它说参数计数不同。我的一位 friend 指导我说 paramVals 数组引用了实际值,这可能会导致问题,可能是由于范围所致。然后我开始创建 Object 类的新对象,然后为它们分配值。这适用于参数计数。但现在的问题是参数类型转换不正确。即使是字符串类型转换为对象(因为它必须是对象数组)也不会被转换回字符串。

文档说调用方法将自行转换它们,如果转换失败,将抛出 IllegalArgumentException。

我没有得到导致调用方法调用失败的原因...

这是框架的代码:

package nttraining.abhay.reflectiondemo;
//imports go here

public class ReflectionFrame
extends JFrame
implements ActionListener, ItemListener{

JComboBox methods;
JButton invokeButton;

public ReflectionFrame(String title) throws HeadlessException {
super(title);
//Layout components

//adding methods of class String to a combo
Class<String> c = String.class;
Method ml[] = c.getMethods();
for(Method m : ml){
methods.addItem(m);
}

invokeButton.addActionListener(this);
methods.addItemListener(this);
}

@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(invokeButton)){
Method selected = (Method) methods.getSelectedItem();
Class paramtypes[] = selected.getParameterTypes();
Object paramVals[] = new Object[paramtypes.length];
System.out.println("Method : " + selected.toString());
for(int i=0; i<paramtypes.length; i++){
Object obj = new Object();
obj = paramtypes[i].cast(params[i].getText());
paramVals[i] = obj;
System.out.println("Added " + paramtypes[i].cast(params[i].getText()).toString() + " to params");
}
try {
result.setText(selected.invoke(object.getText(), params).toString());

} catch (Exception ex) {
System.out.println(ex.getClass().getName() + ": " + ex.getMessage());
}
}
}

@Override
public void itemStateChanged(ItemEvent e) {
Method selected = (Method) methods.getSelectedItem();
if(selected==null)
return;
Class paramtypes[] = selected.getParameterTypes();
int paramCount = paramtypes.length;
object = new JTextField();
paramNames = new JLabel[paramCount];
params = new JTextField[paramCount];
panel.removeAll();
panel.setLayout(new GridLayout(paramCount+1, 2));
panel.add(new JLabel("Calling object"));
panel.add(object);
for(int i=0; i<paramCount; i++){
paramNames[i] = (JLabel) panel.add(new JLabel(paramtypes[i].getName()));
params[i] = (JTextField) panel.add(new JTextField());
}
invalidate();
validate();
}

}

最佳答案

我发现的一个问题是在这一行:
obj = paramtypes[i].cast(params[i].getText());
cast 不转换对象,它仅验证给定对象是否属于某个类。由于您始终提供 String.class 作为参数(通过 .getText()),因此对于除 String 类型参数之外的任何其他参数都会失败。即使 Integer.class 到原始 int 也会失败。

下面的一段代码演示了cast问题。

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class Q21642768 {

public static void main(String[] args) {

try {
// Calls String.indexOf(str, fromIndex) via reflection.
callStringMethod("Hello reflection world", "reflection", 1);
} catch (Exception e) {
e.printStackTrace();
}
}

public static void callStringMethod(String s, String subString, int startIndex) throws Exception {

Class<String> c = String.class;
Method ma[] = c.getMethods();
Method indexOfSub = null;
Class<?>[] indexOfSubPTypes = null;
List<Method> stringMethods = new ArrayList<Method>();
List<Type[]> stringMethodsPTypes = new ArrayList<Type[]>();
for (Method m: ma) {
stringMethods.add(m);
System.out.print(m.getName() + ": ");
Class<?>[] mptypes = m.getParameterTypes();
stringMethodsPTypes.add(mptypes);
boolean first = true;
for (Type t : mptypes) {
if (first) {
first = false;
} else {
System.out.print(", ");
}
System.out.print(t.toString());
}
if ("indexOf".equals(m.getName())
&& mptypes.length == 2
&& mptypes[0].equals(String.class)
&& mptypes[1].equals(int.class)) {
indexOfSub = m;
indexOfSubPTypes = mptypes;
System.out.println(" <-- ");
} else {
System.out.println();
}
}
if (indexOfSub == null) {
System.out.println("target method not found");
return;
}
Object[] pValues = new Object[2];
pValues[0] = indexOfSubPTypes[0].cast(subString);
// Fails:
// pValues[1] = indexOfSubPTypes[1].cast(startIndex);
// pValues[1] = indexOfSubPTypes[1].cast(startIndex + "");
pValues[1] = startIndex;

Object result = indexOfSub.invoke(s, pValues);
System.out.println("Result: " + result);
}

}

关于java.reflection.Method.invoke(...) 不重新转换参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21642768/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com