方法在反射中起作用,但在Java中不是"正常方式"

mar*_*m86 6 java reflection

我执行此代码时遇到异常:

p7 = new PKCS7(p7byte);
...
SignerInfo si = p7.getSignerInfos()[0];
String name = si.getDigestAlgorithmId().getName();
Run Code Online (Sandbox Code Playgroud)

例外是:

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)
Run Code Online (Sandbox Code Playgroud)

代码在IBM机器上执行时抛出此异常,当它在Windows机器上执行时,它正常工作.

研究这个,我发现si.getDigestAlgoritmId()IBM机器的返回类是不同的.对于IBM的java来说,它就是com.ibm.security.x509.AlgorithmIdjava6 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){...}
Run Code Online (Sandbox Code Playgroud)

Pio*_*zmo 2

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

如果使用反射,则不需要getDigestAlgoritmId在编译时声明。它适用于任何声明,只要它与您指定的名称和参数匹配。

小心反思。sun.security.x509.AlgorithmId似乎不属于公共 java API 的一部分。版本和供应商之间可能有所不同。这两者仅在返回类型上有所不同。谁知道其他 Java 实现有什么区别。如果可能,请坚持使用官方 Java API。