标记接口是不定义任何方法的空接口,仅用于为类添加语义标签,使编译器或运行时能通过类型检查识别其特殊能力,如serializable表示可序列化、cloneable表示支持克隆。

Java 中的标记接口(Tag Interface)本身不定义任何方法,它的作用纯粹是“打标签”——让编译器或运行时系统能通过 instanceof 或反射识别某类是否具备某种语义特征。它既不是抽象类,也不需要方法实现,定义方式极简,但使用逻辑清晰。
什么是标记接口
标记接口是一个空的 interface,不含任何方法声明、常量或默认方法。它不提供行为契约,只传递类型层面的元信息。例如:
-
java.io.Serializable—— 表明该类实例可被序列化 -
java.lang.Cloneable—— 表明该类支持浅拷贝(需手动实现clone()) -
java.util.RandomAccess—— 表明列表支持 O(1) 随机访问
如何定义一个标记接口
只需用 interface 关键字声明,不写任何成员:
public interface DeprecatedFeature {
// 空体,无方法、无字段、无注释(可选)
}
之后,让目标接口或类 extends 或 implements 它即可完成“贴标”:
- 若想标记某个接口已过期:让该接口
extends DeprecatedFeature - 若想标记某个类具有审计能力:让该类
implements Auditable(假设Auditable是你定义的空接口)
为什么不用抽象类来实现标记功能
抽象类无法胜任标记职责,原因很直接:
- Java 不支持多继承,一个类只能
extends一个抽象类,但可以implements多个接口 - 抽象类天然携带实现意图(哪怕全是抽象方法),而标记接口强调“零语义负担”
- 标记需在类型系统中自然传播,比如
List extends Serializable>能静态约束泛型边界,抽象类做不到这点
替代方案:现代 Java 更推荐用注解
从 Java 5 起,@interface 注解已成为更灵活、更语义明确的标记手段。例如:
@Deprecated
public interface OldService { ... }
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Experimental { }
相比标记接口,注解优势明显:
- 可标注类、方法、字段、参数等任意元素,粒度更细
- 支持保留策略(
SOURCE/CLASS/RUNTIME),控制何时生效 - 可携带属性(如
@SuppressWarnings("unchecked")),表达更丰富语义
不过,标记接口仍保留在 JDK 核心机制中(如 Serializable),因其能在编译期参与类型检查,且无需反射即可判断。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











