Java反射:获取方法返回参数的类型

Java反射:获取方法返回参数的类型,java,reflection,instantiation,invocationtargetexception,Java,Reflection,Instantiation,Invocationtargetexception,是的,我知道有很多关于这个话题的文章,但不是那么简单 我有一个包装器类,用于将参数一般地传递给方法,然后检索值。这个包装类(称为IDVariant)有一个默认类型,它指示存储的变量的主要类型 因此,我可以: IDVariant v = new IDVariant(1); boolean b = v.booleanValue(); String s = v.stringValue(); int i = v.integerValue(); 依此类推,但根据用于创建实例的参数类型,默认类型将是int

是的,我知道有很多关于这个话题的文章,但不是那么简单

我有一个包装器类,用于将参数一般地传递给方法,然后检索值。这个包装类(称为
IDVariant
)有一个默认类型,它指示存储的变量的主要类型

因此,我可以:

IDVariant v = new IDVariant(1);
boolean b = v.booleanValue();
String s = v.stringValue();
int i = v.integerValue();
依此类推,但根据用于创建实例的参数类型,默认类型将是
int

现在,如前所述,这个类在更大更复杂的类中用作一般占位符。我需要创建一个递归解析类的超级结构的工具,并用XML重新创建这个结构。显然,要走的路是反思,到目前为止,我已经成功地重建了整个事情的结构。唯一的问题是,我没有找到一种方法来找出IDVariant的默认类型,从而为XML树的每个变量提供正确的类型

我尝试的是为每个类的每个属性检索
get
方法,然后调用它并检查每个IDVariant的默认类型。这似乎是一个好主意,但它不起作用:我得到了一个
InvocationTargetException
,我认为这是由于我为调用该方法而创建的类的实例实际上没有填充数据。这是我能给出的唯一合乎逻辑的解释

如果有人有任何想法,我将不胜感激!:)

下面是一个示例代码片段:

// Edit of the code, as correctly indicated by cyon. Tha variable className is given.
Class<?> toParse = Class.forName(className);
Object o = toParse.newInstance();   // There is a default constructor with no values, the object is not null

Class cl = ... // given class
Class[] noparams = {};

String s = "getSomeValue";
Method method = null;
for(Method m : cl.getMethods()) {
    if (m.getName().equals(s)) {
        method = m;
        break;
    }
}

if (method != null) {
    try {
        Object idv = method.invoke(o, noparams);  // exception occurs at this point
        String type = decodeType((IDVariant)idv); // function which maps internal codes of IDVariant default type to primitive and internal types
        return type;
    } catch (InvocationTargetException ex) {
        System.out.println(ex.getCause());
    }
}
所以,也许它在内部试图调用另一个属于超类的方法,而我没有实例化这个超类。这可能就是问题所在吗?如果是,有解决办法吗

编辑2:根据请求,以下是我获得的异常的堆栈跟踪:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at prove.Reflector.getImplicitType(Reflector.java:275)
    at prove.Reflector.recurr(Reflector.java:134)
    at prove.Reflector.ParseToXml(Reflector.java:69)
    at prove.Main.main(Main.java:12)
Caused by: java.lang.NullPointerException
    at com.progamma.doc.IDDocument.GetPropDirect(IDDocument.java:739)
    at it.zerounoesse.Calcolo7302013.Contribuente.getSomeValue(Contribuente.java:70)
... 8 more

当然,您的
IDVariant
类是实例化的,这就是您使用
toParse.newInstance()
方法所做的,但是由于您没有将实例化的对象强制转换为其原始类类型,然后对其进行初始化,因此很可能出现异常,例如NullPointerEx

那么变量
o
中是什么呢?如果
getSomeValue
抛出异常的可能性很高,这是因为
o
中的内容。您是对的,我忘记添加
o
的定义了。我编辑了代码以表明这一点。然而,在调试时,我可以看到对象
o
是实例化的,它拥有它应该拥有的所有值,尽管其中大多数是空的。我是否应该直接调用默认的
构造函数
,而不是使用当前使用的方法?谢谢您抽出时间……:)因为返回类型不是方法签名的一部分。我不知道你问的是否可行。InvocationTargetException下面是什么?潜在的异常是什么?发布堆栈跟踪。阿诺,我认为你是对的。我改变了方法,使用了另一个属性,可以通过动态创建的实例直接使用。我需要确定
IDVariant
的基本类型的代码似乎确实存在于其他地方。但是,我已经按照EJP的要求包含了堆栈跟踪。这是什么意思?构造的对象已初始化。铸造量不会改变这一点。在这种情况下,askers
IDVariant v=新的IDVariant(1)
在构造函数中获取值,因此如果调用空构造函数,则类字段为null=>调用类方法可能会导致NPE。这就是为什么字段初始化需要通过setter(需要强制转换)或通过
构造函数
反射来完成的原因。是的,我认为AWB是正确的。你的帖子让我另辟蹊径,看来我找到了什么。如果它有效,我将在这里发布它以供将来参考。我无法解决最初描述的问题,但我确实设法找到了一个基于自动代码实现的解决方法。我接受awb的答案,因为它似乎是最符合逻辑的解释。再次感谢您的时间:)您的解释无法解释您奇怪的措辞。他调用了错误的构造函数,或者没有进一步初始化对象。这与铸造无关。
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at prove.Reflector.getImplicitType(Reflector.java:275)
    at prove.Reflector.recurr(Reflector.java:134)
    at prove.Reflector.ParseToXml(Reflector.java:69)
    at prove.Main.main(Main.java:12)
Caused by: java.lang.NullPointerException
    at com.progamma.doc.IDDocument.GetPropDirect(IDDocument.java:739)
    at it.zerounoesse.Calcolo7302013.Contribuente.getSomeValue(Contribuente.java:70)
... 8 more