【问题标题】:Why the forEach method in Iterable interface is not abstract? [duplicate]为什么Iterable接口中的forEach方法不是抽象的? [复制]
【发布时间】:2017-08-17 09:40:12
【问题描述】:

当我看到 Iterable 接口源时,看起来foreach 方法和Spliterator 方法不是抽象的。接口如何具有非抽象方法?或者我有什么遗漏吗?见下方Iterbale接口源码。

package java.lang;

import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;

public abstract interface Iterable<T>
{
  public abstract Iterator<T> iterator();

  public void forEach(Consumer<? super T> paramConsumer)
  {
    Objects.requireNonNull(paramConsumer);
    Iterator localIterator = iterator();
    while (localIterator.hasNext())
    {
      Object localObject = localIterator.next();
      paramConsumer.accept(localObject);
    }
  }

  public Spliterator<T> spliterator()
  {
    return Spliterators.spliteratorUnknownSize(iterator(), 0);
  }
}
/* Location:           C:\Program Files\Java\jre1.8.0_121\lib\rt.jar
 * Qualified Name:     java.lang.Iterable
 * Java Class Version: 8 (52.0)
 * JD-Core Version:    0.7.1
 */

【问题讨论】:

  • 是的,Java 8 接口可以有默认方法。阅读 Java 教程,或自 Java 8 出现之前编写的大量博客文章和文章。
  • 这看起来不像实际的源代码。 forEach 应声明为 default。为什么它被声明为abstract interface?你在看什么版本?
  • @Tom 它是 Java 类版本:8 (52.0)
  • 不,不是。它看起来不像那样。除非您使用反编译器而不是查看实际源代码。
  • src.zip 中的类和反编译版本(使用 Fernflower 反编译器)都不是这样。

标签: java foreach interface abstract


【解决方案1】:

使用 Java 8,您可以在接口中定义 default implementation
这就是java.lang.Iterable 所做的:

public interface Iterable<T> {
    ...    
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
   ...
}

您的实际代码并未引用 Java 8 源代码。

【讨论】:

  • 我的代码是指 java 8 源码。 /* 位置:C:\Program Files\Java\jre1.8.0_121\lib\rt.jar * 限定名称:java.lang.Iterable * Java 类版本:8 (52.0) * JD-Core 版本:0.7.1 * /
  • 它是已编译类的可查看版本,而不是类的源代码。这是源代码:grepcode.com/file_/repository.grepcode.com/java/root/jdk/…
  • 我在 eclipse 中看到代码,可能这就是它显示编译版本的原因。
  • 如果Eclipse以这种方式显示源代码,则意味着Eclipse不知道源代码在哪里。在首选项->已安装的 JRE 中,编辑您正在使用的 JDK/JRE。您应该有源附件按钮来指定代码源的位置。
猜你喜欢
  • 2012-03-05
  • 2014-01-02
  • 2012-11-29
  • 2011-06-04
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2012-07-19
  • 2018-12-16
相关资源
最近更新 更多