【问题标题】:Interface with no methods没有方法的接口
【发布时间】:2014-01-19 14:40:07
【问题描述】:
为什么Java会引入一些没有定义方法的接口?例如Cloneable、Serializable、Type 等等。
第二件事:在Class.class 包中定义了一个没有主体的registerNatives() 方法,并从静态块调用,但Class.class 不是抽象的,而是final。为什么这样?
以及为什么 Java 需要从静态块中调用一些没有主体的方法。?
【问题讨论】:
标签:
java
class
interface
java-native-interface
【解决方案1】:
为什么Java会引入一些没有定义方法的接口?
这称为Tagged or Marker interface。这些不用于任何用途或操作。这些方法用于标记或标记一个类。这样您就可以确定 someclass 是否是这些类的子类。
关于第二个问题
如果你仔细看,你可以看到声明是
private static native void registerNatives();
所以registerNatives 是本机方法。
那么什么是原生方法。如果你看到this so question
该方法在“本机”代码中实现。也就是说,代码
不在JVM中运行。它通常用 C 或 C++ 编写。
本机方法通常用于与系统调用或
用其他编程语言编写的库。
所以这些方法是从本地代码加载的。因此,您不需要声明方法的主体,但它们仍然不是抽象的,因为它们的实现来自本机代码。
【解决方案3】:
对于第一个,您实际上是在要求一个标记接口。标记接口的设计不应该向行为添加任何内容,但仅支持对象的多态转换。例如Serializable 使对象能够跨 JVM 边界进行流式传输。标记接口遵循“通用类型替换”理念。
对于第二个,您实际上是在要求 JNI。 Java 并不以 Java 形式实现其所有代码。我的意思是在遵循 Java 语法的类和代码中。有时您需要深入了解本机平台 API 以实现该 API 的某些内容。例如套接字和 TCP 通信。正是 Java 的这一特性实际上使其独立于平台。 JVM 运行时依赖于平台,因为它使用基于平台的本机方法和 dll 或 .so 库来实现和与平台集成。作为程序员,我们调用高级 Java SDK API 调用。
【解决方案4】:
Java 编程语言的“干净”特性之一是它要求将接口(纯行为)和类(状态和行为)分开。 Java 中使用接口来指定派生类的行为。
您经常会在 Java 中遇到没有行为的接口。换句话说,它们只是空的接口定义。这些被称为标记接口。 Java API 中的一些标记接口示例包括:
- java.lang.Cloneable
- java.io.Serializable
- java.util.EventListener
标记接口也称为“标记”接口,因为它们根据用途将所有派生类标记到一个类别中。例如,所有实现 Cloneable 接口的类都可以被克隆(即可以在它们上调用 clone() 方法)。 Java 编译器检查以确保在一个类上调用了 clone() 方法并且该类实现了 Cloneable 接口。例如,考虑以下对对象 o 上的 clone() 方法的调用:
SomeObject o = new SomeObject();
SomeObject ref = (SomeObject)(o.clone());
如果 SomeObject 类没有实现接口 Cloneable(并且 Cloneable 没有被 SomeObject 继承的任何超类实现),编译器会将此行标记为错误。这是因为 clone() 方法只能由“Cloneable”类型的对象调用。因此,即使 Cloneable 是一个空接口,它也有一个重要的用途。