java中的接口

public class ArrayList<E> extends AbstractList<E>
        implements List<E>,

            RandomAccess,

            Cloneable,

            java.io.Serializable

java.util.RandomAccess 接口

翻译:随机存取

jdk中有个RandomAccess接口,这是一个标记接口(Marker),它没有任何方法,这个接口被List的实现类(子类)使用。如果List子类实现了RandomAccess接口,那就表示它能够快速随机访问存储的元素。RandomAccess接口的意义在于:在对列表进行随机或顺序访问的时候,访问算法能够选择性能最佳方式

一般的列表访问算法在访问列表元素之前,都被建议先使用instanceof关键字检查一下列表是否是一个RandomAccess子类,然后再决定采用随机还是顺序方式访问列表中的元素,这样可以保证访问算法拥有最佳的性能。

官网还特意说明了,如果是实现了这个接口的 List,那么使用for循环的方式获取数据会优于用迭代器获取数据

//遍历前先判读是否实现了RandomAccess接口
list instanceof RandomAccess

java.lang.Cloneable 接口

翻译:可复制的,可克隆的

Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:

这里分析一下这个接口的用法,clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类的实例上调用clone方法,否则会抛出CloneNotSupportException。Object中默认的实现是一个浅拷贝,也就是表面拷贝,如果需要实现深层次拷贝的话,必须对类中可变域生成新的实例。

Object提供了一个对象拷贝的默认方法clone方法,但是该方法是有缺陷的,它提供了一种浅拷贝方式,也就是它并不会把对象所有属性全部拷贝一份,而是有选择性的拷贝,拷贝规则如下:

1、基本类型

如果变量是基本类型,则拷贝其值,比如:int、float、long等。

2、String字符串

这个比较特殊,拷贝的是地址,是个引用,但是在修改的时候,它会从字符串池(String Pool)中重新生成新的字符串,原有的字符串对象保持不变,此处可以认为String是个基本类型。

3、对象

如果变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。这在Java中很疯狂,因为它突破了访问权限的定义,一个private修饰的变量,竟然可以被两个实例对象访问。

Cloneable接口如下:如果调用Object的clone方法,没有实现Cloneable接口,则会抛出CloneNotSupportedException

java.io.Serializable

翻译:可串行化的

Serializable接口是启用其序列化功能的接口。实现java.io.Serializable 接口的类是可序列化的。没有实现此接口的类将不能使它们的任意状态被序列化或逆序列化。

序列化

序列化:对象的寿命通常随着生成该对象的程序的终止而终止,而有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法)保存下来,并且可以在需要时再将对象恢复。 Java提供了一种保存对象状态的机制,那就是序列化。

Java 序列化技术可以将一个对象的状态写入一个Byte 流里(序列化),并且可以从其它地方把该Byte 流里的数据读出来(反序列化)。

什么时候需要序列化

想把内存中的对象状态保存到一个文件中或者数据库中时候; 
想把对象通过网络进行传播的时候

如何序列化

只要一个类实现Serializable接口,那么这个类就可以序列化了。

实现了Serializable接口之后,Eclipse就会提示你增加一个 serialVersionUID,虽然不加的话上述程序依然能够正常运行。

 private static final long serialVersionUID = 1L;
 private static final long serialVersionUID = 8683452581122892189L;

序列化 ID 在 Eclipse 下提供了两种生成策略

一个是固定的 1L 
一个是随机生成一个不重复的 long 类型数据(实际上是使用 JDK 工具,根据类名、接口名、成员方法及属性等来生成) 

如果是通过网络传输的话,如果类的serialVersionUID不一致,那么反序列化就不能正常进行。

会报java.io.InvalidClassException异常

序列化只能保存对象的非静态成员交量,不能保存任何的成员方法和静态的成员变量,而且序列化保存的只是变量的值,对于变量的任何修饰符都不能保存。序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。

经常在实现了 Serializable接口的类中能看见transient关键字。 transient关键字的作用是:阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。

当某些变量不想被序列化,同是又不适合使用static关键字声明,那么此时就需要用transient关键字来声明该变量

当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口; 
一个子类实现了 Serializable 接口,它的父类都没有实现 Serializable 接口,要想将父类对象也序列化,就需要让父类也实现Serializable 接口。 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值