根据JLS 15.27.2,lambda 主体与周围上下文具有相同的范围,我想知道是否有特定原因来说明为什么 lambda 实现的接口中的默认方法在主体中也不可用? 此限制是否启用了一些优化,还是只是为了保持重载规则简单?
我今天正在对一些 Java 8 API 进行原型设计,当我遇到这个限制时,我感到非常失望,因为使用默认方法可以让我以一种非常优雅和非侵入性的方式实现该 API。
通过要求静态导入或多或少可以实现相同的优雅,但这会导致“污染”命名空间。
有没有可能取消这个限制?
Collection接口的最小完整定义仅包含两个方法:iterator()和size(),它们是抽象的AbstractCollection.
为什么所有其他方法都没有在Java 8中默认?兼容性应该不是问题,例如,Iterator.remove()在Java 7之前是抽象的,但是从Java 8开始就是默认的.
AbstractCollection当我希望Collection实现成为另一个类层次结构的成员时,子类化有时会很不方便.这不是Java中实际需要接口中的默认方法的原因之一吗?
大约同样的问题Map,List以及其他基本的接口,包括Java集合框架.
UPDATE
Paul Sandoz:
通常,如果有一个令人信服的理由来帮助实现,我们只将接口上的现有抽象方法转换为非抽象方法,例如Iterator.remove.
这些不是Collection上的新方法,并且AbstractCollection中已经有实现.将这些抽象转换为非抽象方法的优势并不是特别引人注目,因为它最有可能从AbstractCollection继承或提供更有效的实现.
可以将AbstractCollection上的所有非抽象方法移动到Collection.如果我们从一张白纸开始,这是我们可能做的.(注意,对于AbstractList上的所有非抽象方法,都不能这样做.)
http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-February/025118.html
我有一个接口和抽象类。
public class TEST extends Abstract implements Inter2{
void print() {
toDO();
}
public static void main(String[] args) {
new TEST().toDO();
}
}
abstract class Abstract {
public void toDO() {
System.out.println("Abstract is called");
}
}
interface Inter2 {
default void toDO() {
System.out.println("Inter2 is called");
}
}
Run Code Online (Sandbox Code Playgroud)
我想强制类接口默认方法而不是抽象类。
延迟接口需要任何接口
此接口的实现[to]定义一个compareTo方法,该方法提供与其getDelay方法一致的排序.
但是我想知道,为什么Java 8中没有默认实现,因为compareTo合同要求完全依赖于getDelay.
有没有具体的理由将其留给实施班?或者在覆盖超级界面时是否无法创建默认方法?
编辑:为了使我的问题更容易理解,这是一个例子:
interface Delayed extends Comparable<Delayed> {
long getDelay(TimeUnit unit);
@Override
default int compareTo(Delayed o) {
// might not be the perfect "compareTo" implementation, but you get the point
return o == this? 0:
Long.compare(this.getDelay(TimeUnit.NANOSECONDS), o.getDelay(TimeUnit.NANOSECONDS);
}
}
Run Code Online (Sandbox Code Playgroud) 在java 8中,默认方法实现可以同时使用public和default修饰符.以下两种方法的主要区别是什么?在哪种条件下需要遵循哪种类型.
default int makeMul(int x, int y) {
return x * y;
}
public default int makeMul(int x, int y) {
return x * y;
}
Run Code Online (Sandbox Code Playgroud) 问题:
我们知道Java不允许扩展多个类,因为它会导致Diamond问题,编译器无法决定使用哪个超类方法.使用接口默认方法,Diamond问题在Java 8中引入.也就是说,因为如果一个类实现两个接口,每个接口定义相同的默认方法,并且实现类不会覆盖常见的默认方法,则编译器无法决定选择哪个实现.
解:
Java 8需要提供由多个接口实现的默认方法的实现.因此,如果一个类实现上面提到的两个接口,它将不得不为常见的默认方法提供一个实现.否则编译器会抛出编译时错误.
题:
通过重写子类引入的常用方法,为什么此解决方案不适用于多类继承?
在 Java 中,一个类只能扩展一个父类,但可以实现多个接口。随着 Java 8 接口中默认方法的引入,通过实现具有相同默认方法的 2 个接口,一个类有可能继承多个具有相同签名的方法 这可能会产生像 C++ 中的菱形问题
在下面的代码示例中的输出
new C().hello(); is
Run Code Online (Sandbox Code Playgroud)
这是第二
public interface First {
default void hello(){
System.out.println("This is First");
}
}
public interface Second extends First {
default void hello(){
System.out.println("This is Second");
}
}
public class MyClass implements First,Second {
public static void main(String[] args) {
new MyClass().hello();
}
}
Run Code Online (Sandbox Code Playgroud)
Java用来解决钻石问题的解析规则是什么?一个简单的答案,比如谁优先,什么时候会很好。
我有类实现多个接口,它们具有相同的默认默认方法.我想知道如何从所有接口合成默认方法.例如:
interface IA {
default void doA() {}
default void process() {
// do something
}
}
interface IB {
default void doB() {}
default void process() {
// do something
}
}
interface IC {
default void doC() {}
default void process() {
// do something
}
}
// other similar interfaces
....
class MyClass implements IA, IB, IC, ... {
public void process() {
// question: how to avoid iterate all the interfaces?
IA.super.process();
IB.super.process();
IC.super.process();
...
} …Run Code Online (Sandbox Code Playgroud) 我正在学习Java 8语法,并在下面的界面中遇到了一段代码:
default EmployeeEnricher employeeEnricher() {
return builder -> {
return;
};
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解上面的语法是什么意思吗?
应用程序中有多个此方法的实现,每个实现都有自己的逻辑.
这可能是一个愚蠢的问题.但我想知道有可能做到这一点.
假设我有类似的界面
public interface GroupIdentifier {
Integer getRevision();
}
Run Code Online (Sandbox Code Playgroud)
我需要另一个名为getNextRevision的方法.所以我能做的是,在同一个接口内部实现默认方法并返回下一个数字.
EX:
public interface GroupIdentifier {
//OUTER GET REVISION
Integer getRevision();
default GroupIdentifier getNextRevisionIdentifier() {
return new GroupIdentifier() {
//INNER GET REVISION
public Integer getRevision() {
//Here I want to return OUTER GET REVISION + 1
return null;
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
这有可能吗?