精华内容
下载资源
问答
  • Effective Jave 创建和销毁对象 4.通过私有构造器强化不可实例能力
    万次阅读
    2017-08-29 09:23:46
    public class Person{
    static{

    }
    public static void Method(){
    ...
    }
    }


    这是属于工具类,不需实例化,类名.方法名 即可调用。


    然而没有显示构造器,但是编译器会默认提供一个公共的、无参的构造器,对于用户而言,与其他构造器并无差别。


    该类可以实例化,也可以子类化,该子类也可以实例化。


    既然是工具类,那么就应该有个明显的标志,这是编码的习惯,也可以提示大码的阅读性。


    public class Person{

    private Person(){
    throw new AssertionError();
    }
    }


    由于显示构造器是私有的,即不可以在类的外部实例化。


    AssertionError不是必须的,只是防止在类的内部实例化。
    更多相关内容
  • 面向对象方法学与结构方法学的异同 面向对象方法与结构方法都是软件开发过程中的方法。在传统的软件开发过程中多采用结构技术完成软件开发的一系列工作,但这种方法并不适应发型软件产品的开发,而随着硬件...

    面向对象方法学与结构化方法学的异同

    面向对象方法与结构化方法都是软件开发过程中的方法。在传统的软件开发过程中多采用结构化技术完成软件开发的一系列工作,但这种方法并不适应发型软件产品的开发,而随着硬件发展,对于大型软件产品的需求又逐步提高,于是面向对象方法就应运而生。面向对象方法在上世纪八十年代中期开始被人们所关注的,而到了九十年代,面向对象方法学已经成为开发大型软件的首选范型。面向对象方法学的极大推广在目前并没有完全取代传统方法学说明了面向对象方法学目前也有缺陷需要进一步提高。那么面向对象方法学和结构化方法学之间的异同点有哪些呢,笔者认为二者不同点主要有以下几个方面:

    一、开发思想方面

    结构化方法开发的背景是在上世纪六十年代末提出软件危机之后,为了应对软件危机,软件开发的先辈们模仿当时比较成熟的工程化生产而提出一种方法。而这种方法也确实减轻或者说缓解了软件危机。结构化方法学的思想是面向过程,自上而下、逐步地分解问题,把一个大问题分解成多个小问题,小问题再分解成多个更小的问题,直到保证底层的问题足够简单,容易解决。

    面向对象方法学在开始,是编程语言而被引入的。而把对象作为编程的实体最早是上世纪六十年代由Simula 67语言引入思维。在结构化方法学提出几年之后,上世纪八十年代面向对象方法学逐渐走上历史的舞台,并在之后乃至现在大放异彩。面向对象方法学的思想是面向对象,以对象为中心,把数据封装在对象内部成为对象的属性,把面向过程的函数转为对象的行为方法,把对象抽象成为类,用以描述和设计、开发软件系统。

    二、基本概念方面

    结构化方法学又被称生命周期方法学或传统方法学。软件从设计者诞生开发想法起始,到没有人用、被废弃结束,称为软件的生命周期。传统的软件开发方法中,软件的生存周期分为三个大的阶段,即软件定义阶段,开发阶段,维护阶段。详细又可以分为问题定义、可行性分析、需求分析、系统设计、系统实现、后期维护等阶段。

    面向对象方法学是一种把面向对象程序设计语言的思想应用于软件开发过程,指导开发过程的方法。面向对象方法学由以下三部分面向对象分析、面向对象设计、面向对象程序设计组成。面向对象开发是按照人的逻辑概念,思维方式去解决问题,使软件开发时的代码重用性和可靠性大大提高。也使软件更容易被人理解,从而提高软件后期运行易维护性。

    三、开发过程方面

    结构化开发分为以下五个阶段

    1、系统规划阶段

    系统规划阶段的内容主要为明确软件的发展规划,确定用户对软件需求,并制定软件开发的计划。

    2、系统分析阶段

    系统分析阶段的内容有解析软件所对应的工作任务,工作任务中的数据和数据流图,软件的功能所需要的技术支持和选择。

    3、系统设计阶段

    系统设计阶段的工作有设计系统总体的结构,相关硬件设施的建设,相关环境的建立与进一步确定和数据库、数据结构设计等。

    4、系统实施阶段

    系统实施阶段的内容为按照上衣阶段的成果,协调技术人员开始编程同时对软件编程开发人员展开培训,测试等相关任务。

    5、系统运行阶段

    系统运行阶段的工作包括以下三个部分即对软件的运行管理,用户评价反馈,后台数据监省察。在软件运行时,一定会出现一些问题,这是也一定需要对软件进行修改,维护和调整,又时甚至会出现影响比较大的问题,如用户需求发生重大改变,相关技术革新,例如网络系统的更新换代,平台的升级更新,虽然这些问题可能出现的时间会比较晚,但也要即使监管并进行相关软件功能或者模块的升级。

    面相对象开发分为以下四个阶段

    1、面向对象分析阶段(OOA)

    这一阶段的工作主要有需求分析以及建立相关需求模型。具体来说就是建立软件中需要的相关的完整的对象,包括这些对象应具有的属性和相关行为。

    2、面向对象设计阶段(OOD)

    这个阶段的主要任务就是将上一阶段得到的需求转化为有技术能力实现的,成本符合预算的并且能够达到用户需求的软件实现方案。具体呢就是确定软件的高层架构,确定需要的类以及对外接口和实现算法等。

    3、面向对象编程阶段(OOP)

    此阶段的工作内容就是实现上一阶段的设计结果,并在编程的过程中修正出现的设计不到位的部分,实现预计的各项功能。

    4、面向对象测试阶段(OOT)

    面向对象测试阶段的主要工作任务就是测试软件各项功能是否存在问题,各项性能如容错性,稳定性,安全性等各项性能,以让软件不断完善。

    四、优劣对比的方面

    结构化方法开发

    优点

    1、传统方法学吧软件的大生命周期分成了许多小的阶段,每一个小阶段又可以分为其他多个不同的阶段,知道每个阶段的任务足够简单,实现相对独立,这样在开发时的分工合作就会比较简单,这样面对一些相同软件便可以流水线式快速高效开发。

    2、在传统方法学软件生命周期每一个阶段都会细细划分,这样也便于科学的管理开发进度使开发工作可以科学条理的开展,而且由于传统方法学中有着非常严格的审查制度,只有审查合格之后才可以进行下一阶段的开发工作。这可以在一定程度上保证软件的质量及其可维护性。而且值得肯定的是这种开发方法由于使用时间较长使其管理层面和技术层面都比较成熟,所以在一些简单的软件开发中,它的效率很高,甚至在当代一些软件开发仍然或多或少地使用传统方法学进行开发。

    缺点

    1、由于传统方法学的开发只能串行开发,前面的工作如果没有做好,就会给后面的工作带来非常大的麻烦,所以它的生产效率总体来说会比较低。

    2、由于其面向过程的局限性,软件的重用性非常差,程序冗余比较严重

    3、因为软件代码冗余比较多,这就会给后期的开发带来许多困难,这就使得软件的可维护性很低,由此带来的软件容错性、稳定性也比较低。

    4.开发出的软件无法很好地满足用户需求。由于用户一般是非专业人员,其所使用的语言逻辑,描述都可能有误差,这就导致呢软件在满足用户需求上效果不佳。

    面向对象方法开发

    优点

    1、面向对象方法学的开发逻辑和人的逻辑思维方法相近。开发大型软件难度相对降低,易被人所理解,同时也可以更好的满足客户需求。
    2、可以灵活的修改软件,软件稳定性高,这就使的后期可维护性有了很大的提高。而后期的软件升级也相对更加容易,更加稳定。

    3、面向对象的程序可重用性有了很大的提高,减少了程序冗余,代码重复,这在一定程度上也降低了开发难度,同时便于维护。

    缺点

    1、面向对象开发也存在着许多弊端,由于面向对象对环境的依赖,虽然大部分拥有了不错的跨平台性能,但需要依赖环境的支持,而相关的开发软件并不全面充分。

    2、面向对象开发不大适合比较大型的信息管理系统开发,而如果从整体设计划分不合理的情况下,会导致系统结构有较大缺陷,关系无法正常分配。

    3、由于其开发逻辑思维与人相似,所以无法从科学的角度管理和优化开发。

    五、对以上总结如下:

    传统方法学编程是以过程为中心的,尽量把大的程序划分为许多个相对独立、功能尽可能简单的小的程序模块,其强调重视过程,重视功能的结构化,和简单化。最终实现功能是通过一系列过程的调用和处理来完成。虽然经过时间累积开发人员们的不断完善,传统开发方法一直都有新的成果,模式出现,但无可避免的被面向对象开发方法所冲击。

    面向对象编程是将对象作为中心的,其功能的实现是对一系列相关对象的操作,给对象发送消息,再由对象来执行相对应的一系列操作并返回结果,重在强调对象。而在理论上,面向对象的程序设计方法可以生产更良好的模块内聚和耦合特性,更好得实现软件开发的逻辑原则,这也使得面向对开发的软件更易于重用与维护,也相对更加稳定,质量也相对更高。

    展开全文
  • 对象的序列化 对象序列化就是把一个对象变为二进制数据流的一种方法。 一个类要想被序列化,就行必须实现java.io.Serializable接口。...先让我们实现一个具有序列化能力的类吧: 1 2 3 4 5 6 7 8 9 1

    Java 序列化Serializable详解(附详细例子)

    1、什么是序列化和反序列化
    Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。


    2、什么情况下需要序列化
    a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
    b)当你想用套接字在网络上传送对象的时候;
    c)当你想通过RMI传输对象的时候;

    3、如何实现序列化

    将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。


    4、序列化和反序列化例子

    如果我们想要序列化一个对象,首先要创建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream(记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构)。而反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputstream、ByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。


    6.序列化前和序列化后的对象的关系

    是 "=="还是equal? or 是浅复制还是深复制?

    答案:深复制,反序列化还原后的对象地址与原来的的地址不同

    序列化前后对象的地址不同了,但是内容是一样的,而且对象中包含的引用也相同。换句话说,通过序列化操作,我们可以实现对任何可Serializable对象的”深度复制(deep copy)"——这意味着我们复制的是整个对象网,而不仅仅是基本对象及其引用。对于同一流的对象,他们的地址是相同,说明他们是同一个对象,但是与其他流的对象地址却不相同。也就说,只要将对象序列化到单一流中,就可以恢复出与我们写出时一样的对象网,而且只要在同一流中,对象都是同一个。


    7.静态变量能否序列化


    为何把最上面代码的age变量添上static 后还是反序列化出了24呢?而新的从新对变量赋值的代码,不是static的得到了序列化本身的值,而static的则得到的是从新附的值。原因: 序列化会忽略静态变量,即序列化不保存静态变量的状态。静态成员属于类级别的,所以不能序列化。即 序列化的是对象的状态不是类的状态。这里的不能序列化的意思,是序列化信息中不包含这个静态成员域。注:transient后的变量也不能序列化,但是情况稍复杂。


    8、总结:

    a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

    b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

    c) static,transient后的变量不能被序列化;


    当我们查看产生的hello.txt的时候,看到的是乱码,呵呵。因为是二进制文件。


    Externalizable接口

    被Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。

    当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。


    一、序列化和反序列化的概念

      把对象转换为字节序列的过程称为对象的序列化
      把字节序列恢复为对象的过程称为对象的反序列化
      对象的序列化主要有两种用途:
      1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
      2) 在网络上传送对象的字节序列。

      在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

      当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

    二、JDK类库中的序列化API

      java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
      java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
      只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。
      对象序列化包括如下步骤:
      1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
      2) 通过对象输出流的writeObject()方法写对象。

      对象反序列化的步骤如下:
      1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
      2) 通过对象输入流的readObject()方法读取对象。

    对象序列化和反序列范例:

      定义一个Person类,实现Serializable接口

    复制代码
     1 import java.io.Serializable;
     2 
     3 /**
     4  * <p>ClassName: Person<p>
     5  * <p>Description:测试对象序列化和反序列化<p>
     6  * @author xudp
     7  * @version 1.0 V
     8  * @createTime 2014-6-9 下午02:33:25
     9  */
    10 public class Person implements Serializable {
    11 
    12     /**
    13      * 序列化ID
    14      */
    15     private static final long serialVersionUID = -5809782578272943999L;
    16     private int age;
    17     private String name;
    18     private String sex;
    19 
    20     public int getAge() {
    21         return age;
    22     }
    23 
    24     public String getName() {
    25         return name;
    26     }
    27 
    28     public String getSex() {
    29         return sex;
    30     }
    31 
    32     public void setAge(int age) {
    33         this.age = age;
    34     }
    35 
    36     public void setName(String name) {
    37         this.name = name;
    38     }
    39 
    40     public void setSex(String sex) {
    41         this.sex = sex;
    42     }
    43 }
    复制代码

      序列化和反序列化Person类对象

    复制代码
     1 import java.io.File;
     2 import java.io.FileInputStream;
     3 import java.io.FileNotFoundException;
     4 import java.io.FileOutputStream;
     5 import java.io.IOException;
     6 import java.io.ObjectInputStream;
     7 import java.io.ObjectOutputStream;
     8 import java.text.MessageFormat;
     9 
    10 /**
    11  * <p>ClassName: TestObjSerializeAndDeserialize<p>
    12  * <p>Description: 测试对象的序列化和反序列<p>
    13  * @author xudp
    14  * @version 1.0 V
    15  * @createTime 2014-6-9 下午03:17:25
    16  */
    17 public class TestObjSerializeAndDeserialize {
    18 
    19     public static void main(String[] args) throws Exception {
    20         SerializePerson();//序列化Person对象
    21         Person p = DeserializePerson();//反序列Perons对象
    22         System.out.println(MessageFormat.format("name={0},age={1},sex={2}",
    23                                                  p.getName(), p.getAge(), p.getSex()));
    24     }
    25     
    26     /**
    27      * MethodName: SerializePerson 
    28      * Description: 序列化Person对象
    29      * @author xudp
    30      * @throws FileNotFoundException
    31      * @throws IOException
    32      */
    33     private static void SerializePerson() throws FileNotFoundException,
    34             IOException {
    35         Person person = new Person();
    36         person.setName("gacl");
    37         person.setAge(25);
    38         person.setSex("男");
    39         // ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
    40         ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
    41                 new File("E:/Person.txt")));
    42         oo.writeObject(person);
    43         System.out.println("Person对象序列化成功!");
    44         oo.close();
    45     }
    46 
    47     /**
    48      * MethodName: DeserializePerson 
    49      * Description: 反序列Perons对象
    50      * @author xudp
    51      * @return
    52      * @throws Exception
    53      * @throws IOException
    54      */
    55     private static Person DeserializePerson() throws Exception, IOException {
    56         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
    57                 new File("E:/Person.txt")));
    58         Person person = (Person) ois.readObject();
    59         System.out.println("Person对象反序列化成功!");
    60         return person;
    61     }
    62 
    63 }
    复制代码

    代码运行结果如下:

    序列化Person成功后在E盘生成了一个Person.txt文件,而反序列化Person是读取E盘的Person.txt后生成了一个Person对象

     三、serialVersionUID的作用

      s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​号​,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

    1 private static final long serialVersionUID

      实现Serializable接口的类如果类中没有添加serialVersionUID,那么就会出现如下的警告提示

      

      用鼠标点击就会弹出生成serialVersionUID的对话框,如下图所示:

      

      serialVersionUID有两种生成方式:

      采用这种方式生成的serialVersionUID是1L,例如:

    1 private static final long serialVersionUID = 1L;

      采用这种方式生成的serialVersionUID是根据类名,接口名,方法和属性等来生成的,例如:

    1 private static final long serialVersionUID = 4603642343377807741L;

      添加了之后就不会出现那个警告提示了,如下所示:

      

      扯了那么多,那么serialVersionUID(序列化版本号)到底有什么用呢,我们用如下的例子来说明一下serialVersionUID的作用,看下面的代码:

    复制代码
     1 import java.io.File;
     2 import java.io.FileInputStream;
     3 import java.io.FileNotFoundException;
     4 import java.io.FileOutputStream;
     5 import java.io.IOException;
     6 import java.io.ObjectInputStream;
     7 import java.io.ObjectOutputStream;
     8 import java.io.Serializable;
     9 
    10 public class TestSerialversionUID {
    11 
    12     public static void main(String[] args) throws Exception {
    13         SerializeCustomer();// 序列化Customer对象
    14         Customer customer = DeserializeCustomer();// 反序列Customer对象
    15         System.out.println(customer);
    16     }
    17 
    18     /**
    19      * MethodName: SerializeCustomer 
    20      * Description: 序列化Customer对象
    21      * @author xudp
    22      * @throws FileNotFoundException
    23      * @throws IOException
    24      */
    25     private static void SerializeCustomer() throws FileNotFoundException,
    26             IOException {
    27         Customer customer = new Customer("gacl",25);
    28         // ObjectOutputStream 对象输出流
    29         ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
    30                 new File("E:/Customer.txt")));
    31         oo.writeObject(customer);
    32         System.out.println("Customer对象序列化成功!");
    33         oo.close();
    34     }
    35 
    36     /**
    37      * MethodName: DeserializeCustomer 
    38      * Description: 反序列Customer对象
    39      * @author xudp
    40      * @return
    41      * @throws Exception
    42      * @throws IOException
    43      */
    44     private static Customer DeserializeCustomer() throws Exception, IOException {
    45         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
    46                 new File("E:/Customer.txt")));
    47         Customer customer = (Customer) ois.readObject();
    48         System.out.println("Customer对象反序列化成功!");
    49         return customer;
    50     }
    51 }
    52 
    53 /**
    54  * <p>ClassName: Customer<p>
    55  * <p>Description: Customer实现了Serializable接口,可以被序列化<p>
    56  * @author xudp
    57  * @version 1.0 V
    58  * @createTime 2014-6-9 下午04:20:17
    59  */
    60 class Customer implements Serializable {
    61     //Customer类中没有定义serialVersionUID
    62     private String name;
    63     private int age;
    64 
    65     public Customer(String name, int age) {
    66         this.name = name;
    67         this.age = age;
    68     }
    69 
    70     /*
    71      * @MethodName toString
    72      * @Description 重写Object类的toString()方法
    73      * @author xudp
    74      * @return string
    75      * @see java.lang.Object#toString()
    76      */
    77     @Override
    78     public String toString() {
    79         return "name=" + name + ", age=" + age;
    80     }
    81 }
    复制代码

    运行结果:

    序列化和反序列化都成功了。

    下面我们修改一下Customer类,添加多一个sex属性,如下:

    复制代码
     1 class Customer implements Serializable {
     2     //Customer类中没有定义serialVersionUID
     3     private String name;
     4     private int age;
     5 
     6     //新添加的sex属性
     7     private String sex;
     8     
     9     public Customer(String name, int age) {
    10         this.name = name;
    11         this.age = age;
    12     }
    13     
    14     public Customer(String name, int age,String sex) {
    15         this.name = name;
    16         this.age = age;
    17         this.sex = sex;
    18     }
    19 
    20     /*
    21      * @MethodName toString
    22      * @Description 重写Object类的toString()方法
    23      * @author xudp
    24      * @return string
    25      * @see java.lang.Object#toString()
    26      */
    27     @Override
    28     public String toString() {
    29         return "name=" + name + ", age=" + age;
    30     }
    31 }
    复制代码

      然后执行反序列操作,此时就会抛出如下的异常信息:

    1 Exception in thread "main" java.io.InvalidClassException: Customer; 
    2 local class incompatible: 
    3 stream classdesc serialVersionUID = -88175599799432325, 
    4 local class serialVersionUID = -5182532647273106745

      意思就是说,文件流中的class和classpath中的class,也就是修改过后的class,不兼容了,处于安全机制考虑,程序抛出了错误,并且拒绝载入。那么如果我们真的有需求要在序列化后添加一个字段或者方法呢?应该怎么办?那就是自己去指定serialVersionUID。在TestSerialversionUID例子中,没有指定Customer类的serialVersionUID的,那么java编译器会自动给这个class进行一个摘要算法,类似于指纹算法,只要这个文件 多一个空格,得到的UID就会截然不同的,可以保证在这么多类中,这个编号是唯一的。所以,添加了一个字段后,由于没有显指定 serialVersionUID,编译器又为我们生成了一个UID,当然和前面保存在文件中的那个不会一样了,于是就出现了2个序列化版本号不一致的错误。因此,只要我们自己指定了serialVersionUID,就可以在序列化后,去添加一个字段,或者方法,而不会影响到后期的还原,还原后的对象照样可以使用,而且还多了方法或者属性可以用。

      下面继续修改Customer类,给Customer指定一个serialVersionUID,修改后的代码如下:

    复制代码
     1 class Customer implements Serializable {
     2     /**
     3      * Customer类中定义的serialVersionUID(序列化版本号)
     4      */
     5     private static final long serialVersionUID = -5182532647273106745L;
     6     private String name;
     7     private int age;
     8 
     9     //新添加的sex属性
    10     //private String sex;
    11     
    12     public Customer(String name, int age) {
    13         this.name = name;
    14         this.age = age;
    15     }
    16     
    17     /*public Customer(String name, int age,String sex) {
    18         this.name = name;
    19         this.age = age;
    20         this.sex = sex;
    21     }*/
    22 
    23     /*
    24      * @MethodName toString
    25      * @Description 重写Object类的toString()方法
    26      * @author xudp
    27      * @return string
    28      * @see java.lang.Object#toString()
    29      */
    30     @Override
    31     public String toString() {
    32         return "name=" + name + ", age=" + age;
    33     }
    34 }
    复制代码

      重新执行序列化操作,将Customer对象序列化到本地硬盘的Customer.txt文件存储,然后修改Customer类,添加sex属性,修改后的Customer类代码如下:

    复制代码
     1 class Customer implements Serializable {
     2     /**
     3      * Customer类中定义的serialVersionUID(序列化版本号)
     4      */
     5     private static final long serialVersionUID = -5182532647273106745L;
     6     private String name;
     7     private int age;
     8 
     9     //新添加的sex属性
    10     private String sex;
    11     
    12     public Customer(String name, int age) {
    13         this.name = name;
    14         this.age = age;
    15     }
    16     
    17     public Customer(String name, int age,String sex) {
    18         this.name = name;
    19         this.age = age;
    20         this.sex = sex;
    21     }
    22 
    23     /*
    24      * @MethodName toString
    25      * @Description 重写Object类的toString()方法
    26      * @author xudp
    27      * @return string
    28      * @see java.lang.Object#toString()
    29      */
    30     @Override
    31     public String toString() {
    32         return "name=" + name + ", age=" + age;
    33     }
    34 }
    复制代码

    执行反序列操作,这次就可以反序列成功了,如下所示:

      

    四、serialVersionUID的取值

      serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
      类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值

      显式地定义serialVersionUID有两种用途:
        1、 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
        2、 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。


    展开全文
  • 按虚拟化对象划分,虚拟存储实现方式主要有三种。 虚拟存储的三种实现方式 基于主机的虚拟存储 基于主机的虚拟存储依赖于代理或管理软件,它们安装在一个或多个主机上,实现存储虚拟的控制和管理。由于控制...

    存储虚拟化最通俗的理解就是对存储硬件资源进行抽象化表现。按虚拟化对象划分,虚拟化存储实现方式主要有三种。

    虚拟化存储的三种实现方式

    基于主机的虚拟存储

    基于主机的虚拟存储依赖于代理或管理软件,它们安装在一个或多个主机上,实现存储虚拟化的控制和管理。由于控制软件是运行在主机上,这就会占用主机的处理时间。因此,这种方法的可扩充性较差,实际运行的性能不是很好。基于主机的方法也有可能影响到系统的稳定性和安全性,因为有可能导致不经意间越权访问到受保护的数据。

    这种方法要求在主机上安装适当的控制软件,因此一个主机的故障可能影响整个SAN系统中数据的完整性。软件控制的存储虚拟化还可能由于不同存储厂商软硬件的差异而带来不必要的互操作性开销,所以这种方法的灵活性也比较差。但是,因为不需要任何附加硬件,基于主机的虚拟化方法最容易实现,其设备成本最低。使用这种方法的供应商趋向于成为存储管理领域的软件厂商,而且目前已经有成熟的软件产品。这些软件可以提供便于使用的图形接口,方便地用于SAN的管理和虚拟化,在主机和小型SAN结构中有着良好的负载平衡机制。从这个意义上看,基于主机的存储虚拟化是一种性价比不错的方法。

    基于存储设备的虚拟化

    基于存储设备的存储虚拟化方法依赖于提供相关功能的存储模块。如果没有第三方的虚拟软件,基于存储的虚拟化经常只能提供一种不完全的存储虚拟化解决方案。对于包含多厂商存储设备的SAN存储系统,这种方法的运行效果并不是很好。依赖于存储供应商的功能模块将会在系统中排斥JBODS(JustaBunchofDisks,简单的硬盘组)和简单存储设备的使用,因为这些设备并没有提供存储虚拟化的功能。

    当然,利用这种方法意味着最终将锁定某一家单独的存储供应商。基于存储的虚拟化方法也有一些优势:在存储系统中这种方法较容易实现,容易和某个特定存储供应商的设备相协调,所以更容易管理,同时它对用户或管理人员都是透明的。但是,我们必须注意到,因为缺乏足够的软件进行支持,这就使得解决方案更难以客户化(customization)和监控。

    基于网络的虚拟存储

    1)基于互联设备的虚拟化

    基于互联设备的方法如果是对称的,那么控制信息和数据走在同一条通道上;如果是不对称的,控制信息和数据走在不同的路径上。在对称的方式下,互联设备可能成为瓶颈,但是多重设备管理和负载平衡机制可以减缓瓶颈的矛盾。同时,多重设备管理环境中,当一个设备发生故障时,也比较容易支持服务器实现故障接替。但是,这将产生多个SAN孤岛,因为一个设备仅控制与它所连接的存储系统。非对称式虚拟存储比对称式更具有可扩展性,因为数据和控制信息的路径是分离的。

    基于互联设备的虚拟化方法能够在专用服务器上运行,使用标准操作系统,例如Windows、SunSolaris、Linux或供应商提供的操作系统。这种方法运行在标准操作系统中,具有基于主机方法的诸多优势——易使用、设备便宜。许多基于设备的虚拟化提供商也提供附加的功能模块来改善系统的整体性能,能够获得比标准操作系统更好的性能和更完善的功能,但需要更高的硬件成本。但是,基于设备的方法也继承了基于主机虚拟化方法的一些缺陷,因为它仍然需要一个运行在主机上的代理软件或基于主机的适配器,任何主机的故障或不适当的主机配置都可能导致访问到不被保护的数据。同时,在异构操作系统间的互操作性仍然是一个问题。

    2)基于路由器的虚拟化

    基于路由器的方法是在路由器固件上实现存储虚拟化功能。供应商通常也提供运行在主机上的附加软件来进一步增强存储管理能力。在此方法中,路由器被放置于每个主机到存储网络的数据通道中,用来截取网络中任何一个从主机到存储系统的命令。由于路由器潜在地为每一台主机服务,大多数控制模块存在于路由器的固件中,相对于基于主机和大多数基于互联设备的方法,这种方法的性能更好、效果更佳。由于不依赖于在每个主机上运行的代理服务器,这种方法比基于主机或基于设备的方法具有更好的安全性。

    当连接主机到存储网络的路由器出现故障时,仍然可能导致主机上的数据不能被访问。但是只有联结于故障路由器的主机才会受到影响,其他主机仍然可以通过其他路由器访问存储系统。路由器的冗余可以支持动态多路径,这也为上述故障问题提供了一个解决方法。由于路由器经常作为协议转换的桥梁,基于路由器的方法也可以在异构操作系统和多供应商存储环境之间提供互操作性。

    人工智能、大数据、云计算和物联网的未来发展值得重视,均为前沿产业,多智时代专注于人工智能和大数据的入门和科谱,在此为你推荐几篇优质好文:
    什么是虚拟化技术,虚拟化主要分几种?
    http://www.duozhishidai.com/article-1776-1.html
    云计算与虚拟化有哪些异同之处,虚拟化就是云计算吗?
    http://www.duozhishidai.com/article-1674-1.html
    虚拟化技术搭建的云计算平台,相对于传统方式有哪些优势?
    http://www.duozhishidai.com/article-1165-1.html


    多智时代-人工智能大数据学习入门网站|人工智能、大数据、物联网云计算的学习交流网站

    多智时代-人工智能大数据学习入门网站|人工智能、大数据、云计算、物联网的学习服务的好平台

    展开全文
  • Java动态给序列JSON添加对象

    千次阅读 2019-04-18 20:27:59
    工作中,将亚马逊接口通用的时候。需要将订单明细B 加入到订单主体A中。并且自定义属性AmazonOrderDetail。 正常的操作是新建对象 C 将属性分别赋值就行了。 但是我是通用接口。只知道SDK中的ClassName. 于是就...
  • **spring boot 集成 activeMQ 传输序列化对象首先下载个mq - -这里用的是windows7 64位的 启动运行即可。当然也可以使用springboot 集成在本地的叫一个什么broker的包,百度一下即可,一般不会使用内置的mq。**1....
  • Java基础——对象的序列(通俗易懂,排版优美)

    万次阅读 多人点赞 2018-05-23 23:31:23
    Java基础——对象的序列什么是对象的序列(Serialization) “序列”是一种把对象的状态转化成字节流的机制,“反序列”是其相反的过程,把序列化成的字节流用来在内存中重新创建一个实际的Java对象。...
  • 面向对象的方法与生俱来很强的应对需求变更能力。能从容应对客户的需求变更。 对结构方法来说,它的先天缺陷是需求变更很难,一旦要需求变更,意味着以前一切的工作都是徒劳的。 三、管理维护的难易程度不同 ...
  • 结构方法和面向对象方法的比较

    千次阅读 2018-10-31 16:50:00
    结构方法和面向对象方法的比较 翁松秀 北京航空航天大学  摘要:编程之精髓在于编程思想,而不同的编程方法有不同的编程思想。结构程序设计方法一直以来都是编程人员基本的编程方法,而近年来流行的面向对象...
  • 面向对象设计思想-基本概念

    千次阅读 2020-12-22 19:42:31
    面向对象最需要的是 抽象的能力。 这个能力需要通过大量编写代码和思考系统结构来获得。类与类的关系,包与包的关系,项目与项目的关系。 架构师的抽象能力要更深一层,代码结构,数据结构,文件结构,项目结构,...
  • 开源对象存储MinIO技术白皮书

    万次阅读 多人点赞 2019-09-27 13:38:36
    ——采用尽可以简单可靠的集群管理方案,摒弃复杂的大规模集群调度管理,减少风险因素与性能瓶颈,聚焦产品的核心功能,打造高可靠的集群、灵活的扩展能力以及超高的性能;   积木式扩展 ——建立众多的中小规模...
  • 万字长文深度剖析面向对象的javascript

    万次阅读 热门讨论 2020-12-02 09:46:56
    本将会深入讲解面向对象在javascript中的应用,并详细介绍三种对象的生成方式:构造函数,原型链,类。
  • C++ 对象 & 类

    千次阅读 多人点赞 2021-05-02 02:12:24
    C++ 对象 (Object) 和 类 (Class) 简介
  • jquery.param()实现数组或对象的序列

    千次阅读 2017-05-16 10:03:54
    创建适用于URL查询字符串或Ajax请求的数组,普通对象或jQuery对象的序列表示形式。 如果jQuery对象被传递,它应该包含具有name / value属性的输入元素。 jQuery.param( obj ): obj: 类型:Array或...
  • 前两篇介绍了对象存储的基础,包括存储类型,常用存储分类和分类方法。 SCSI,TCP/IP,FC等存储介质以及DAS\NAS\SAN等存储网络,请参考:对象存储1:传统存储类型和分类。 文件存储,块存储以及对象存储等数据存储...
  • Java对象的序列就是把一个对象变成二进制的数据流的一中方法,通过对象的序列可以方便的实现对象的传输和存储。 原理是:对象------------->转换----------------->将对象转变为二进制的数据  在对象序列时,...
  • 本书由著名编程理论专家所著,是美国麻省理工学院电子工程与计算机科学系的编程实践课程教材。...本书非常适合作为软件学院的教材,在低年级即可培养学生对于事物的抽象能力。此外,本书也非常适合软件开发人员参考。
  • JDK1.8——Java对象的创建过程

    千次阅读 2020-08-16 20:22:20
    对象的创建 Java是一门面向对象的编程语言,Java程序运行过程中无时无刻都有对象被创建出来。 对象创建过程概述 对象的创建过程如图: 这里解释一下什么是符号引用: 符号引用: 符号引用是一个字符串,它给出了被...
  • 在JS中复制对象

    千次阅读 2021-04-01 11:34:21
    渣翻译,有英文阅读能力的可以去原网址阅读,正文部分的括号内是译者的尝试补充说明 自豪地采用谷歌翻译 在这篇文章中,我将会讲到几种在JS中复制对象的方式,我们将会关注到浅复制和深复制。 在开始之前,值得一提...
  • Redis对象读写序列

    千次阅读 2015-08-21 16:05:45
    在使用Redis中,将对象序列以Json方式写入Redis的方法: 基本推荐使用JdkSerializationRedisSerializer和StringRedisSerializer,因为其他两个序列策略使用起来配置很麻烦,如果实在有需要序列成Json和XML格式...
  • 华为数字转型实践

    千次阅读 2022-03-30 11:10:49
    本篇文章基于华为自身数字转型实践,以及与行业客户和伙伴在转型过程中总结提炼出可供大中型企业借鉴的,加速数字转型和智能升级的方法论和落地方案,介绍如何通过数字技术,在数字研发、数字生产、数字...
  • Java引用对象

    万次阅读 2018-12-11 10:09:03
    在这一步,GC会移动对象使回收的对象留下的空闲空间合并,这可以防止堆变得碎片,避免大块相邻内存分配的失败。 例如,Hotspot JVM,在新生代使用会压缩的回收器,而在老年代使用非压缩的回收器(至少在1.6和...
  • java提高篇(五)-----使用序列实现对象的拷贝

    万次阅读 多人点赞 2013-10-22 19:15:06
    我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常明显。...
  • 面向对象

    千次阅读 2018-03-21 14:23:06
    面向对象 一封装 二多态 三继承面向对象一、封装封装是对象和类概念的主要特性。它是隐藏内部实现,稳定外部接口,可以看作是“包装”。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让...
  • java对象的序列 ...java中存有Cloneable接口,实现此接口的类都具有被拷贝能力,比new一个对象要快,拷贝分为浅拷贝和深拷贝,浅拷贝导致对象属性不彻底。 class Professor { String name; int age; Prof
  • 对象的串行(Serialization)

    千次阅读 2013-10-18 11:42:49
    一、串行的概念和目的  ...我们把对象的这种能记录自己的状态以便将来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己 ,这个过程叫对象的串行(Serialization) 。串行
  • JVM - 对象的创建

    万次阅读 2022-02-02 15:14:05
    JVM - 对象的创建
  • Java技能点--序列与反序列

    万次阅读 2017-11-07 17:41:47
    一,概述对象的序列与反序列其实就是将对象的状态保存下来,一般是保存到文件中,但是其实更常用的是将对象的序列化为字符串保存到数据库中,然后在需要读取对象情况的时候反序列化为对象。二,Serializable接口...
  • 对象存储是什么?看过就明白了

    千次阅读 多人点赞 2019-12-12 10:52:15
    对象存储,官方的名词解释是:对象存储是基于对象的存储,是用来描述解决和处理离散单元的方法的通用术语,这些离散单元被称作对象。 说实话看完这段解释,我的内心是这样的: 这时候如果再继续介绍: 对象存储提供...
  • 面向对象与结构编程区别及异同

    千次阅读 2016-04-25 12:44:16
    结构编程的语言主流的是c语言,采用结构的编程方式,主要用来编写操作系统。特点:语言灵活非常接近底层,对硬件有强大的访问能力。对于一个比较复杂的系统,往往是自顶向下,逐步求精,分模块的思想来编写。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 631,193
精华内容 252,477
关键字:

对象化能力