装饰类、序列化和反序列化

装饰器的作用就是动态扩展某一个类的功能

/**

  • 装饰器模式
  • 1)不使用继承
  • 2)不改变原类的文件
  • 3)动态扩展
  • Component: InputStream
  • 统一接口,装饰类/被装饰类的基本接口
  • ConcreteComponent FileInputStream
  • 具体实现类(被装饰类),它本身是一个比较完整的类
  • Decorator: FilterInputStream
  • 装饰类,实现Component接口同时还会在内部维护一个ConcreateComponent的实例,并且
  • 这个实例是在构造函数中初始化
  • ConcreteDecorator BufferInputStream
  • 具体的装饰类,每一种装饰产品都有不同的装饰效果
  • 组合 利用已存在类的功能,在新类中创建一个原有类的实例
  •   显示的
    
  • 继承 描述一种"是"的关系 利用已存在类的功能,新类继承原有类
  •  当父类被修改,会影响到所有继承它的子类,增加维护难度和成本
    
  •  隐式的
    
  • 例:Transport Car Bus Tyre
  • Car Bus is Transport 继承
  • Car has mang Tyres/ Bus has many Tyres 组合

*/

装饰类的一个简单实现,用于理解
Component :被装饰类接口
ConcreteComponent :具体实现类(被装饰类)
Decorator:装饰类(可以理解为经纪人)
ConcreteDecorator:具体实现类(演员本人)

interface Component{
    
    
    void method();
}

/**
 * 被装饰类
 */
class ConcreteComponent implements Component{
    
    

    @Override
    public void method() {
    
    
        System.out.println("concreteComponent method");
    }
}

/**
 * 装饰类 实现Component接口
 */
abstract class Decorator implements Component{
    
    
    //内部会维护一个ConcreateComponent的实例
    private Component component;

    //这个实例是在构造函数中初始化
    public Decorator(Component component){
    
    
        this.component = component;
    }

    @Override
    public void method() {
    
    
        component.method();
    }
}

/**
 * 具体装饰类A类
 */
class ConcreteDecoratorA extends Decorator{
    
    

    public ConcreteDecoratorA(Component component) {
    
    
        super(component);
    }

    public void methodA1(){
    
    
        System.out.println("装饰器A所实现的功能1");
    }

    public void methodA2(){
    
    
        System.out.println("装饰器A所实现的功能2");
    }
}

/**
 * 具体装饰类B类
 */
class ConcreteDecoratorB extends Decorator{
    
    

    public ConcreteDecoratorB(Component component) {
    
    
        super(component);
    }

    public void methodB1(){
    
    
        System.out.println("装饰器B所实现的功能1");
    }

    public void methodB2(){
    
    
        System.out.println("装饰器B所实现的功能2");
    }
}

public class TestDemo6 {
    
    
    public static void main(String[] args) {
    
    
        //被装饰的对象
        Component component = new ConcreteComponent();
        //被装饰的对象本身具有的功能
        component.method();
        //装饰成A
        ConcreteDecoratorA a = new ConcreteDecoratorA(component);
        a.method();
        a.methodA1();
        a.methodA2();

        //装饰成B
        ConcreteDecoratorB b = new ConcreteDecoratorB(component);
        b.method();
        b.methodB1();
        b.methodB2();
    }
}

序列化和反序列化

/**

  • Java中序列化与反序列化
  • 类中的对象会随这程序的终止被垃圾回收器而销毁,如果在不想要创建对象的情况下
  • 调用该类中的功能,考虑使用序列化将原有的对象转换为字节流存到磁盘上
  • 对象的序列化:对象-》字节流 永久保存至磁盘文件或者网络传送
  • 对象的反序列化:字节流-》对象
  • 一个凭他上序列化的对象在不同平台都可以被反序列化
  • 面试题:序列化机制存在的意义?
  • 对象的序列化机制允许将Java对象转换为字节流,这些字节流可以永久地保存在磁盘
  • 上,或者咋网络中传输,从一个网络节点到另外一个网络节点,可以使得某一个对象
  • 脱离原有的程序能够对立存在,其他程序一旦获取到当前的字节流,都可以将这种字节
  • 流恢复为原有的对象。
  • 如何实现对象的序列化:
  • 1)对象所在类实现Serializable接口,使用Serializable接口实现序列化
    1. 创建ObjectOutputStream,这个输出流是一个处理流,所以必须建立在其他
  • 节点流的基础上
  • 3)调用ObjectOutputStream对象的writeObject去序列化对象
  • 如何实现对象的额反序列化:
  • 1)创建ObjectInputStream,这个输入流是一个处理流,所以必须建立在其他
  • 节点流的基础上
  • 2)调用ObjectInputStream对象readObject方法读取流中对象
  • 注意:
  • 1)反序列读取到的只是Java对象,提供当前对象所属的类
  • 2)Person只有一个构造器,同时反序列化时没有打印当前构造器中的内容,那就
  • 说明这里并没有初始化对象
  • 3)当一个序列化的类如果有多个父类的,这些父类要么提供一个无参构造器,要么
  • 就也得实现序列化接口,如果以上都没有则表示父类是不可被序列化的
  • 什么是serialVersionUID?
  • 如果某个对象保存在磁盘上,那么序列化的时候就会根据该对象的哈希码生成serialVersionUID
  • 标记在当前的对象上,用于对象的版本控制。当修改原有的类,反序列化时没有办法将原有的对象
  • 恢复,因为serialVersionUID已经为新类重新生成
  • ArrayList中的序列化和反序列化
  • ArrayList重写了writeObject和readObejct方法控制序列化过程
  • 注意:tranisent关键字修饰的属性不参与序列化与反序列化的过程
  • 当一个变量前加上这个关键字,在序列化的规程中该变量不会写入,而
  • 反序列化之后该变量会是对应类型的初始值
  • 调用到ArrayList中writeObject的过程?
  • ObjectOutPutStream.writeObject
  • ->writeObject0
  • ->writeOrdinaryObject
  • ->writeSerialData
  • ->invokeWriteObject 反射机制
    */
package io;

import java.io.*;
import java.util.ArrayList;



```java

    class Person implements Serializable{
    
    
        private String name;
        private int age;

        public Person(String name, int age) {
    
    
            System.out.println("实例化Person对象");
            this.name = name;
            this.age = age;
        }

        public String getName() {
    
    
            return name;
        }

        public void setName(String name) {
    
    
            this.name = name;
        }

        public int getAge() {
    
    
            return age;
        }

        public void setAge(int age) {
    
    
            this.age = age;
        }
    }
    public class TestDemo7 {
    
    
        public static void main(String[] args){
    
    
            ArrayList<String> stringList = new ArrayList<>();
            stringList.add("hello");
            stringList.add("world");
            stringList.add("hello");
            stringList.add("tulun");

            ObjectOutputStream oos = null;
            ObjectInputStream ois = null;
            try {
    
    
                //序列化
                oos = new ObjectOutputStream(new FileOutputStream("stringList.txt"));
                oos.writeObject(stringList);

                //反序列化
                ois = new ObjectInputStream(new FileInputStream("stringList.txt"));
                ArrayList<String> newStringList = (ArrayList)ois.readObject();
                System.out.println(newStringList);
            } catch (IOException e) {
    
    
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                try {
    
    
                    oos.close();
                    ois.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        //序列化一个Person对象
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;

        try {
    
    
            //创建一个ObjectOutputStream
            oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
            //创建一个ObjectInputStream
            ois = new ObjectInputStream(new FileInputStream("a.txt"));
            //调用writeObject实现序列化
            Person person = new Person("tulun", 18);
            oos.writeObject(person);

            //通过readObect实现反序列化
            Person p = (Person)ois.readObject();
            System.out.println(p.getName()+": "+p.getAge());
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                oos.close();
                ois.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }

猜你喜欢

转载自blog.csdn.net/weixin_47198561/article/details/113111319