java8:处理默认方法
在编写加密实用程序类时,我遇到了以下方法的问题:
public static void destroy(Key key) throws DestroyFailedException {
if(Destroyable.class.isInstance(key)) {
((Destroyable)key).destroy();
}
}
@Test
public void destroySecretKeySpec() {
byte[] rawKey = new byte[32];
new SecureRandom().nextBytes(rawKey);
try {
destroy(new SecretKeySpec(rawKey , "AES"));
} catch(DestroyFailedException e) {
Assert.fail();
}
}
在上述方法的特定情况下,由于SecretKeySpec(javadocs 7)不实现Destroyable(javadocs 7),因此可以正常工作。javax.crypto.spec.SecretKeySpec
java7
现在,使用类SecretKeySpec(javadocs 8)已经变得可销毁(javadocs 8),并且方法Destroyable#destroy现在是,根据此语句,这很好java8
default
默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性。
然后代码编译没有任何问题,尽管类本身没有被更改,单独的接口SecretKey已经。ScretKeySpec
问题是,该方法中具有以下实现:oracle's jdk8
destroy
public default void destroy() throws DestroyFailedException {
throw new DestroyFailedException();
}
这会导致运行时出现异常。
因此,二进制兼容性可能没有被破坏,但现有的代码已经被破坏了。上述测试通过,但未通过java7
java8
所以我的问题是:
-
通常如何处理可能导致异常(因为未实现或不支持)或运行时意外行为的默认方法?除了做
Method method = key.getClass().getMethod("destroy"); if(! method.isDefault()) { ((Destroyable)key).destroy(); }
它只对java8有效,在将来的发行版中可能不正确,因为默认方法可能会得到一个有意义的实现。
将此默认方法留空而不是抛出异常(IMO具有误导性,因为除了合法调用销毁任何东西都没有尝试有效地销毁密钥之外,不受支持的操作异常会更合适,您会立即知道发生了什么)不是更好吗?
-
是我的方法(类型检查/投射/调用)
if(Destroyable.class.isInstance(key)) ((Destroyable)key).destroy();
用于确定是否要破坏错误?有什么替代方案?
这是一种误解,还是他们只是忘记在中添加有意义的实现?
ScretKeySpec