今天看到一个很有意思的问题,如果我定义了一个接口,但是是空的,有什么作用呢?
苦思冥想了很久,作为一个个渣渣!我觉得竟然是个空接口!有和没有有个毛的区别啊!!!!
后来在论坛上看到了一个大牛,给了我想要的解答,醍醐灌顶一般!
下面是他的回答,使用了serializable这个接口做的例子,我不知道咋直接转过来额,就复制过来了
给你看个简单的例子,你就明白了
package cn.please.serializable;
import java.io.Serializable;
//实现此标识接口的类,其中不含任何方法
class A implements Serializable {
}
// 类B没有实现Serializable接口
class B {
}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
// A的实例对象 a 同样可以作为是Serializable类型 ,类B则不行
System.out.println(a instanceof Serializable); //output: true
System.out.println(b instanceof Serializable); //output: false
}
}
java在进行序列化操作时候,会用类似instanceOf (具体怎么样的不清楚,你可以参考源码看看,只是推测)的方法来检查要序列化的对象是否实现了serializable接口 ,如果没有实现 则会抛出NotSerializableException 异常,表明该对象没有实现此接口,不能序列化.
事实上你自己以后进行类的架构设计时,可以考虑类似的方法:
满足实现某一接口的类能被某种操作进行筛选的条件。 你只想知道这个类是符合我的条件而已,我不需要这个类去实现多余的方法,所以标识接口就比较有用了.
就Serializable接口来说,类要去实现序列化有很大的代价,虽然只是简单的实现了这个这么一个标识接口,主要在于:
1. 一旦这个类实现了序列化接口,假如被发布使用,就大大降低了“改变这个类的实现”的灵活性. 因为这个类的字节流编码就变成了它导出API的一部分,一旦这个类被广泛使用,必须的保持这样的形式。使得类的演变收到限制,比如它和序列号UID有直接关系
2. 增加了出现bug和安全漏洞的可能性
3. 使得测试负担加重.
序列化是一个很复杂的问题,要被序列化的类实现标识接口很简单,但在使用ObjectOutputStream类似的流对该对象进行序列化处理时候,是非常繁杂和困难的,考虑的因素非常多...
这也许是为什么不是JDK设计之初不让默认任何对象序列化的原因之一吧,因为即使你标识为该接口声明能序列化,但实际上很多因素在一起 不一定可以,而且带来的问题很多,使得类的扩展性受限.
你可以看看《Effective java中文版(第二版)》第11章74条,详细解释了为什实现序列化接口的谨慎和带来的潜在问题...
看了你就明白。
另外,jdk中也有个Cloneable标识接口,但这个接口实际上作用并没有达到效果。
通常情况下,实现标识接口就是为了表明该类是否属于某中特定的类型,至于符合这样的类型的类,该怎么处理,就看你程序中是如何处理而已。标识下这个类而已.
说的实在是太好了!!如果一个类需不需要执行一种特定的功能是未知的,不防设置一个空接口来做判断!