Java中的反射方法有效,但“正常方式”无效

6
我执行这段代码时遇到了一个异常:
p7 = new PKCS7(p7byte);
...
SignerInfo si = p7.getSignerInfos()[0];
String name = si.getDigestAlgorithmId().getName();

异常信息如下:

Exception in thread "main" java.lang.NoSuchMethodError: sun/security/pkcs/SignerInfo.getDigestAlgorithmId()Lsun/security/x509/AlgorithmId;
        at reflex.Reflex.testPKCS7(Reflex.java:151)
        at reflex.Reflex.main(Reflex.java:43)

当代码在IBM机器上执行时,会抛出此异常。当在Windows机器上执行时,它可以正常工作。
研究后发现,对于si.getDigestAlgoritmId()的返回类在IBM机器上是com.ibm.security.x509.AlgorithmId,在java6中是sun.security.x509.AlgorithmId,并且这两个类都有一个getName()方法。
但最奇怪的是,如果我通过反射调用该方法,则不会出现异常,并且在两个环境中都可以正常工作。有人能解释为什么吗?
我认为解决方案是使用反射,但我想知道为什么反射可以工作而普通方式不行。主要是为了避免将来出现类似错误。
提前感谢您的帮助,非常抱歉我的英语不好。
编辑: 反射调用:
try{
  Class clase = si.getClass();
  Method metodo = clase.getMethod("getDigestAlgorithmId");
  Object result = metodo.invoke(si,null); 
  System.out.println("Result.class=" + result.getClass().getName());
  System.out.println("Result=" + result);
}catch(Exception e){...}

1
如果您能添加使用反射调用该方法的方式,那将非常好。 - Luiggi Mendoza
1个回答

2

SignerInfo.getDigestAlgoritmId()在这两个Java版本中的声明不同。如果您使用其中一个声明编译类,则它将无法与另一个版本一起使用。该类型存储在您的.class文件中,必须在运行时匹配。

如果您使用反射,则不需要在编译时声明getDigestAlgoritmId。只要名称和参数匹配,它就可以与任何声明一起使用。

请注意反射。 sun.security.x509.AlgorithmId似乎不是公共Java API的一部分。它可能因版本和供应商而异。这两个版本仅在返回类型上有所不同。谁知道其他Java实现中存在哪些差异。如果可能,请坚持使用官方Java API。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接