Java 标记接口(Serializable/Cloneable/RandomAccess)

简介:Java中的标记接口(Marker Interface),又称标签接口,是个空接口,对于实现了标记接口的类,可以在运行时通过反射机制去获取元数据,现在Spring中的注解(Annotation)已经成了维护元数据的最好方式。

一、Serializable

  1. 作用:实现java.io.Serializable接口,可以将类进行序列化和反序列化;

  2. 概念组

    A. 序列化:指把对象转换为字节序列的过程;

    B. 反序列化:指把字节序列恢复成对象的过程;

  3. 为保证serialVersionUID值跨不同Java编译器实现的一致性,序列化类必须声明一个明确的serialVersionUID值。

 

二、Cloneable

  1. 对象创建方式

    A. 使用new操作符创建一个对象,但new出来的对象的属性都还是初始化的值;

    B. 使用clone方法复制一个对象,而clone的对象包含对象存在的属性值,且clone是通过navtive底层实现,所以比set速度快;

   2. 克隆分类:浅拷贝和深拷贝,主要区别在于是否支持引用类的成员变量的复制

   3. 浅拷贝(ShallowClone)

    A. 定义:如果原型对象的成员变量是基本数据类型,将复制一份给拷贝对象;如果原型对象的成员变量是引用类型,就将引用对象的地址复制一份给拷贝对象(二者指向相同的内存地址);

    B. 实现步骤

      第一步:被复制的类需要实现java.lang.Cloneable标记接口,否则调用clone方法会抛出CloneNotSupportedException异常;

      第二步:覆盖clone方法,访问修饰符设为public,调用super.clone()方法得到需要的拷贝对象;

    C. 示例

package com.ruhuanxingyun.javabasic.clone;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @description: 浅克隆
 * @author: ruphie
 * @date: Create in 2020/10/20 21:08
 * @company: ruhuanxingyun
 */
public class ShallowClone {

    public static void main(String[] args) throws CloneNotSupportedException {
        Skill skill = new Skill("跳远");
        Student student1 = new Student("张三", 19, skill);
        // 数据拷贝
        Object student2 = student1.clone();

        System.out.println("是否相等:" + (student1 == student2));
        System.out.println("student1:" + student1 + ",student2:" + student2);

        student1.setName("李四");
        skill.setSkillName("拔河");
        System.out.println("student1:" + student1 + ",student2:" + student2);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class Student implements Cloneable {

        /**
         * 姓名
         */
        private String name;

        /**
         * 年龄
         */
        private Integer age;

        /**
         * 技能对象
         */
        private Skill skill;

        /**
         * 注:方法的权限修饰符改为public
         */
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class Skill {

        /**
         * 技能
         */
        private String skillName;

    }

}

  4. 深拷贝(DeepClone)

    A. 定义:无论原型对象的成员变量是基本数据类型还是引用类型,都将复制一份给拷贝对象,深克隆将原型对象的所有引用对象也复制一份给拷贝对象;

    B. 实现方式

      方式一:通过覆盖Object类的clone()方法实现;

      方式二:通过序列化(Serialization)方式实现;

    C. 多层拷贝问题:指引用类型里面包含很多引用类型,或者内层引用类型的类里面又包含引用类型,需用使用序列化的方式来解决;

    D. 示例

package com.ruhuanxingyun.javabasic.clone;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @description: 深克隆
 * @author: ruphie
 * @date: Create in 2020/10/20 21:38
 * @company: ruhuanxingyun
 */
public class DeepClone {

    public static void main(String[] args) throws CloneNotSupportedException {
        Skill skill = new Skill("跳远");
        Student student1 = new Student("张三", 19, skill);
        // 数据拷贝
        Object student2 = student1.clone();

        System.out.println("是否相等:" + (student1 == student2));
        System.out.println("student1:" + student1 + ",student2:" + student2);

        student1.setName("李四");
        skill.setSkillName("拔河");
        System.out.println("student1:" + student1 + ",student2:" + student2);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class Student implements Cloneable {

        /**
         * 姓名
         */
        private String name;

        /**
         * 年龄
         */
        private Integer age;

        /**
         * 技能对象
         */
        private Skill skill;

        /**
         * 注:方法的权限修饰符改为public
         *     深克隆不能简单的调用父类clone方法
         */
        @Override
        public Object clone() throws CloneNotSupportedException {
            Student student = (Student) super.clone();
            Skill skill = (Skill) this.skill.clone();
            student.setSkill(skill);

            return student;
        }

    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class Skill implements Cloneable {

        /**
         * 技能
         */
        private String skillName;

        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

    }

}

 

三、RandomAccess

  1. 作用:实现接口java.util.RandomAccess,用来表明其支持快速(通常是固定时间)随机访问,主要目的是允许一般的算法更改其行为,从而在将其应用到随机或连续访问列表时能提供良好的性能;

  2. 应用:如果List实现了该接口,那么使用for循环的方式获取数据的性能会优于用迭代器获取数据。

List<String> list = new ArrayList<>(3);
list.add("aa");
list.add("bb");
list.add("cc);

// 随机访问
for
(int i = 0, len = list.size(); i < len; i++) { list.get(i); }
// 顺序访问 ​
for (Iterator it = list.iterator(); it.hasNext(); ) { it.next(); }

 

posted @ 2020-08-22 10:37  如幻行云  阅读(336)  评论(0编辑  收藏  举报