标记接口
标记接口是计算机科学中的一种设计模式。它不含有任何属性和方法。其作用是:当某个类实现了这个接口的时候,我们就认为该类拥有了标记接口所描述的功能。
其着眼点在于“标记”(标记拥有某一个功能),而“接口”只是作为一种实现方式。而注解是更加优雅的实现方式。
Java中常见的几种标记接口
Serializable
这个接口是用来标记类是否支持序列化的,所谓的序列化就是将对象的各种信息转换成可以存储或者传输的一种形式。
Cloneable
它的作用是标识该对象是否拥有克隆自己的能力。
RandomAccess
这个接口的作用是判断集合是否支持随机访问,也就是通过索引下标能否快速的定位到到对应的元素上。
使用
if(obj instanceof Marker Interface) {
}
比如Collections类的shuffle方法的实现:
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
如果容器实现RandomAccess
接口,则可以使用更加快速的随机访问。
缺点
并不是说实现了这个接口,类就拥有了某种能力,而是反过来,一个类先拥有了某种能力,然后作者给它打上一个标记,声明我这个类拥有这种能力。
比如我们实现了Cloneable
接口还必须实现Object.clone()
方法,否则抛CloneNotSupportedException
异常。
注解实现
import org.junit.Test;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
}
@MyAnnotation
class MyMaker {
@MyAnnotation
public void show() {
}
}
public class Test4 {
@Test
public void test1() throws NoSuchMethodException {
System.out.println(MyMaker.class.getMethod("show").isAnnotationPresent(MyAnnotation.class));
System.out.println(MyMaker.class.isAnnotationPresent(MyAnnotation.class));
System.out.println(MyAnnotation.class.isAnnotation());
}
}