私有接口方法,示例用例?
Posted
技术标签:
【中文标题】私有接口方法,示例用例?【英文标题】:Private interface methods, example use-case? 【发布时间】:2015-05-16 10:36:35 【问题描述】:“对于接口中的私有方法的支持曾一度考虑包含在 Java SE 8 中,作为增加对 Lambda 表达式支持的努力的一部分,但为了更好地专注于 Java SE 8 的更高优先级任务而被撤回。它是现在提议支持私有接口方法,从而使接口的非抽象方法能够在它们之间共享代码。”
http://openjdk.java.net/jeps/213 的规范如此说,并在错误报告中说https://bugs.openjdk.java.net/browse/JDK-8071453。
但我真的想不出任何必要的用例,即使上面给出了简短的解释。我可以问一个“私有接口方法”在代码方面有用的例子吗?
编辑:所以答案是,由于 Java 8 中如何将默认实现添加到接口中,因此可能存在默认实现使用相同代码库的情况。
例如,
public interface MyInterface
default void initializeMyClass(MyClass myClass, Params params)
//do magical things in 100 lines of code to initialize myClass for example
default MyClass createMyClass(Params params)
MyClass myClass = new MyClass();
initializeMyClass(myClass, params);
return myClass;
default MyClass createMyClass()
MyClass myClass = new MyClass();
initializeMyClass(myClass, null);
return myClass;
愚蠢的例子,我知道。但是假设我们想在这两种方法中使用initializeMyClass(MyClass, Params)
。但是,如果我们这样做(默认方法),那么initializeMyClass(MyClass, Params)
将成为公共接口的一部分!为了防止这种情况发生,我们只能将整个initializeMyClass(MyClass, Params)
的代码保留在createMyClass()
默认方法中。这会导致代码重复,这是不可取的。
因此,这会导致重构出现问题,为了消除这种代码重复,允许使用私有默认方法。
感谢您的回答!
【问题讨论】:
【参考方案1】:接口现在可以有default methods。添加这些是为了可以将新方法添加到接口中,而不会破坏实现这些更改的接口的所有类。
如果两个默认方法需要共享代码,私有接口方法将允许它们这样做,但不会通过接口公开该私有方法及其所有“实现细节”。
【讨论】:
这些方法基本上是语法糖来调用静态方法,否则这些方法可能是包私有的吗? 不,因为您可以在实现中将它们作为实例方法覆盖,如果您使用静态方法,这是您无法做到的。 这样的压倒一切如何工作?覆盖可以访问什么,什么可以访问覆盖? 我现在意识到您可能在谈论私有接口方法,而我假设我们在谈论默认方法:) 我不知道私有方法将如何实现,但我不知道不要认为他们会使用静态方法,因为您经常希望使用其他实例方法来计算结果。也许这值得提出自己的问题...... 那么,为什么不使用抽象类呢?想说:对于一个界面来说,它们不是太多东西吗?我将接口视为合同,而不是实现,并且为了 lambdas 我接受默认方法,但我认为这已经失控......他们应该允许多重继承并停止它。【参考方案2】:为什么不简单(简单地 = 使用 Java8):
PS: 因为私有助手在 Java 中是不可能的
public interface MyInterface
private static class Helper
static initializeMyClass(MyClass myClass, Params params)
//do magical things in 100 lines of code to initialize myClass for example
default MyClass createMyClass(Params params)
MyClass myClass = new MyClass();
Helper.initializeMyClass(myClass, params);
return myClass;
default MyClass createMyClass()
MyClass myClass = new MyClass();
Helper.initializeMyClass(myClass, null);
return myClass;
【讨论】:
好技巧,可能是因为它不太方便,但它是一个好技巧! 我在“年龄”中广泛使用此类助手。从我的 POV 来看,编程语言以这种方式扩展来实现这样的目的有点奇怪,增加了不必要的复杂性。 私有静态类不能在这里用我的 Eclipse 编译 @maxim_ge 我不知道你的编译器怎么允许你使用这样的声明!!!但它不能与我的 Java 8u131 一起编译,除非我对Helper
类使用公共或包级别!
@maxim_ge 仅当您从类声明中删除 private 和 static 关键字时才会编译。即使这样,这也与接口中的私有方法不同。您仍然可以通过键入 MyInterface.Helper
访问 Helper
类。接口中的私有方法是完全隐藏的,并且无法从接口外部访问。【参考方案3】:
Java 9 允许在接口内声明私有方法。 这是它的例子。
interface myinterface
default void m1(String msg)
msg+=" from m1";
printMessage(msg);
default void m2(String msg)
msg+=" from m2";
printMessage(msg);
private void printMessage(String msg)
System.out.println(msg);
public class privatemethods implements myinterface
public void printInterface()
m1("Hello world");
m2("new world");
public static void main(String[] args)
privatemethods s = new privatemethods();
s.printInterface();
为此,您需要将 jdk 更新到 1.9 版本。
【讨论】:
以上是关于私有接口方法,示例用例?的主要内容,如果未能解决你的问题,请参考以下文章
使用 FakeItEasy 的私有方法和属性的单元测试用例 [重复]