接口实现重写它自己的方法来创建一个自己的对象作为 DEFAULT

Interface implements overriding its own methods to create an object of itself as DEFAULT

我已经阅读了很多主题,其中的问题看起来像是我要问的问题。但是,我找不到可以应用于我的问题的满意答案,因为我的问题不止一倍,分为三个方面。

这是https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java

中的SubtitleDecoderFactory接口

据我所知,接口是抽象的,不能有具体的方法实现(也许新 java 允许这样做,但由于我是 java 的新手,让我们坚持一般规则Java)。所以在我看来接口中有两个抽象方法声明是有意义的,它们是"boolean supportsFormat(Format format)"和"SubtitleDecoder createDecoder(Format format)"。但我不明白的是,我的问题是:

  1. 为什么这个接口可以实现"SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()",貌似是初始化方法的实现?

  2. 这个接口通过重写自己的方法来初始化自己,是不是无意义的动作? (一个接口应该有其他 classes 来实现它,而不是它本身,我说得对吗?)

  3. 假设问题 1 和 2 有效,在接口中创建自身的对象有什么好处?

  4. 是不是实现了这个接口的class实例会有这个接口的DEFAULT实例?


public interface SubtitleDecoderFactory {


  boolean supportsFormat(Format format);


  SubtitleDecoder createDecoder(Format format);


  SubtitleDecoderFactory DEFAULT =
      new SubtitleDecoderFactory() {

        @Override
        public boolean supportsFormat(Format format) {
          @Nullable String mimeType = format.sampleMimeType;
          return MimeTypes.TEXT_VTT.equals(mimeType)
              || MimeTypes.TEXT_SSA.equals(mimeType)
              || MimeTypes.APPLICATION_TTML.equals(mimeType)
              || MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
              || MimeTypes.APPLICATION_SUBRIP.equals(mimeType)
              || MimeTypes.APPLICATION_TX3G.equals(mimeType)
              || MimeTypes.APPLICATION_CEA608.equals(mimeType)
              || MimeTypes.APPLICATION_MP4CEA608.equals(mimeType)
              || MimeTypes.APPLICATION_CEA708.equals(mimeType)
              || MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)
              || MimeTypes.APPLICATION_PGS.equals(mimeType);
        }

        @Override
        public SubtitleDecoder createDecoder(Format format) {
          @Nullable String mimeType = format.sampleMimeType;
          if (mimeType != null) {
            switch (mimeType) {
              case MimeTypes.TEXT_VTT:
                return new WebvttDecoder();
              case MimeTypes.TEXT_SSA:
                return new SsaDecoder(format.initializationData);
              case MimeTypes.APPLICATION_MP4VTT:
                return new Mp4WebvttDecoder();
              case MimeTypes.APPLICATION_TTML:
                return new TtmlDecoder();
              case MimeTypes.APPLICATION_SUBRIP:
                return new SubripDecoder();
              case MimeTypes.APPLICATION_TX3G:
                return new Tx3gDecoder(format.initializationData);
              case MimeTypes.APPLICATION_CEA608:
              case MimeTypes.APPLICATION_MP4CEA608:
                return new Cea608Decoder(mimeType, format.accessibilityChannel);
              case MimeTypes.APPLICATION_CEA708:
                return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
              case MimeTypes.APPLICATION_DVBSUBS:
                return new DvbDecoder(format.initializationData);
              case MimeTypes.APPLICATION_PGS:
                return new PgsDecoder();
              default:
                break;
            }
          }
          throw new IllegalArgumentException(
              "Attempted to create decoder for unsupported MIME type: " + mimeType);
        }
      };
}

new SubtitleDecoderFactory() { ... } 创建一个 anonymous inner class that implements the interface SubtitleDecoderFactory. This instance is then assigned to the static field DEFAULT ("Every field declaration in the body of an interface is implicitly public, static, and final", JLS, §9.3).

的实例

在程序的其余部分,可以通过 SubtitleDecoderFactory.DEFAULT.

访问匿名 class 的实例
  1. Why can this interface implements "SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()", which looks like an implementation of initializing method?

接口没有实现任何东西。您拥有的是一个名为 publicstaticfinal 字段 的字段 DEFAULT,它被分配了一个 SubtitleDecoderFactory 的实例.


  1. This interface initializes itself by overriding its own methods, is it an meaningless action? (an interface is meant to have other classes to implement it, not itself, am I correct?)

同样,接口不是 "initializing itself" 也不是实现自身。您拥有的是 匿名 class 的示例。正是这个匿名 class 正在实施 SubtitleDecoderFactory。实例化匿名class,实例赋值给DEFAULT字段;当 Class 初始化 .

时会发生这种情况
  1. What are the benifits of creating an object of itself in an interface, assuming questions 1 and 2 are valid?

在这种情况下,提供了 SubtitleDecoderFactory 的默认实现。这个默认实现也只有一个实例,因为在接口中声明的所有字段都是隐式 public、静态和最终的;这是 单例.

的示例

这里的一个可能优势是您不必声明另一个名为 class 的名称。由于目标显然是拥有一个单身人士,因此也没有 需要 命名 class。


  1. Is it that an instance of a class which implements this interface will have the instance of DEFAULT of this intetface [sic]?

请记住 DEFAULT 是一个引用匿名 class 实例的字段。 SubtitleDecoderFactory 的所有实现都可以访问该字段吗?是的,但不是特别是因为他们正在实现接口。

由于在接口中声明的所有字段都是 public、静态的和最终的 DEFAULT 字段是 常量(尽管不是 编译时间常量)。静态字段与 class 而不是 class 的实例相关联。换句话说,任何可以 "see" SubtitleDecoderFactory 的 class 都可以访问 DEFAULT 字段。例如:

/* import SubtitleDecoderFactory interface as needed */

public class Main {

  public static void main(String[] args) {
    System.out.println(SubtitleDecoderFactory.DEFAULT == SubtitleDecoderFactory.DEFAULT);
  }

}