引入Java 8时,我们可以在接口中使用默认方法。 此功能的主要驱动程序是允许扩展接口,同时保留对旧接口版本的向后兼容性。 一个示例是在现有Collection类中引入stream()方法。
有时,当我们想引入几种默认方法时,它们可能共享一些通用的代码库,因此,如果我们可以在接口中使用私有方法,那就太好了。 这样,我们可以重用我们的代码,还可以防止代码暴露给正在使用或正在实现接口的类。
但有一个问题。 接口中的私有和受保护的访问已推迟到Java9。那么,今天如何在Java 8中使用私有接口方法?
一个简单的解决方案
假设我们有两个方法Foo 。 bar()和bazz()都将返回一些难以计算的结果,这些结果是从这样的共享代码发出的:
public interface Foo {
default int bar() {
return complicatedMethodWithManyLinesOfCode();
}
default int bazz() {
return complicatedMethodWithManyLinesOfCode() + 1;
}
// Will not work in Java 8 because interface methods cannot be private!
private int complicatedMethodWithManyLinesOfCode() {
// Actual code not shown...
return 0;
}
}
通过引入一个包含私有方法的class ,我们可以从外部访问中“隐藏”该方法,并且几乎可以摆脱Java 8接口中的私有方法。 可以这样完成:
public interface Foo {
default int bar() {
return Hidden.complicatedMethodWithManyLinesOfCode();
}
default int bazz() {
return Hidden.complicatedMethodWithManyLinesOfCode() + 1;
}
class Hidden {
private static int complicatedMethodWithManyLinesOfCode() {
// Actual code not shown...
return 0;
}
}
}
从外部类或接口看不到方法Foo:complicatedMethodWithManyLinesOfCode但是可以看到Hidden类本身。 但是,如果它们是私有的,则看不到“ Hidden方法和字段。
此方案也可以应用于受保护的接口方法访问。 从技术上讲,我们可以在一个接口中扩展Hidden类,该接口还可以扩展原始接口Foo 。 请记住,受保护的方法也是包可见的,因此,如果我们扩展或使用同一包中的接口,则受保护的方法也是可见的(与以往一样)。
一个缺点是隐藏方法无法访问接口中的其他方法。 通过使隐藏的静态方法采用接口类型的参数,可以轻松地解决后一个缺点。 假设complicatedMethodWithManyLinesOfCode方法需要从Foo接口获取另一个值,该值可以通过名为buzz()某些接口方法获得,则它看起来可能像这样:
public interface Foo {
default int bar() {
return Hidden.complicatedMethodWithManyLinesOfCode(this);
}
default int bazz() {
return Hidden.complicatedMethodWithManyLinesOfCode(this) + 1;
}
int buzz();
class Hidden {
private static int complicatedMethodWithManyLinesOfCode(Foo foo) {
// Actual code not shown...
return 0 + foo.buzz();
}
}
}
翻译自: https://www.javacodegeeks.com/2016/03/java-8-declare-private-protected-methods-interfaces.html
在Java8中,虽然不能直接在接口内声明私有或受保护方法,但可通过引入内部静态类来实现代码复用及隐藏。文章介绍了一种技巧,即在接口中创建一个静态内部类,用于存放那些需要保持私有且不对外暴露的方法。
785

被折叠的 条评论
为什么被折叠?



