问题
I've read many threads with questions which looks like questions I am going to ask. However, I can not find satisfactory answers which could be applied to my questions, since there are more than one fold in my questions, seperated in three aspects.
This is the interface SubtitleDecoderFactory in https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java
As I understand, an interace is abstraction and can not have concrete implementation of methods (maybe new java allows this, but since I am new to java, let's stick with the genaral rules of Java). So It makes sense to me that there are two absract mothod declarations in the interface, which are "boolean supportsFormat(Format format)" and "SubtitleDecoder createDecoder(Format format)". But what I don't understand and my questions are:
Why can this interface implements "SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()", which looks like an implementation of initializing method?
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?)
What are the benifits of creating an object of itself in an interface, assuming questions 1 and 2 are valid?
Is it that an instance of a class which implements this interface will have the instance of DEFAULT of this intetface?
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);
}
};
}
回答1:
- Why can this interface implements "SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()", which looks like an implementation of initializing method?
The interface is not implementing anything. What you have is a public
, static
, final
field named DEFAULT
which is assigned an instance of SubtitleDecoderFactory
.
- 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?)
Again, the interface is not "initializing itself" nor implementing itself. What you have is an example of an anonymous class. It is this anonymous class which is implementing SubtitleDecoderFactory
. The anonymous class is instantiated and the instance is assigned to the DEFAULT
field; this happens when the Class
is initialized.
- What are the benifits of creating an object of itself in an interface, assuming questions 1 and 2 are valid?
In this case, a default implementation of SubtitleDecoderFactory
is being provided. There's also only ever a single instance of this default implementation, since all fields declared in an interface are implicitly public, static, and final; this is an example of a singleton.
One possible advantage here is you don't have to declare another named class. And since the goal is apparently to have a singleton, there's no need for a named class either.
- Is it that an instance of a class which implements this interface will have the instance of DEFAULT of this intetface [sic]?
Remember that DEFAULT
is a field which references an instance of an anonymous class. Will all implementations of SubtitleDecoderFactory
have access to this field? Yes, but not specifically because they are implementing the interface.
Since all fields declared in an interface are public, static, and final the DEFAULT
field is a constant (though not a compile-time constant). Static fields are associated with the class instead of instances of that class. In other words, any class which can "see" SubtitleDecoderFactory
has access to the DEFAULT
field. For example:
/* import SubtitleDecoderFactory interface as needed */
public class Main {
public static void main(String[] args) {
System.out.println(SubtitleDecoderFactory.DEFAULT == SubtitleDecoderFactory.DEFAULT);
}
}
回答2:
new SubtitleDecoderFactory() { ... }
creates an instance of an 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).
In the rest of the program, the instance of the anonymous class is accessible through SubtitleDecoderFactory.DEFAULT
.
来源:https://stackoverflow.com/questions/59494282/interface-implements-overriding-its-own-methods-to-create-an-object-of-itself-as