本文着重解说一下Java序列化的相关内容。

假设对Java序列化感兴趣的同学能够研究一下。

一.Java序列化的作用

   有的时候我们想要把一个Java对象变成字节流的形式传出去,有的时候我们想要从一个字节流中恢复一个Java对象。比如。有的时候我们想要

把一个Java对象写入到硬盘或者传输到网路上面的其他计算机,这时我们就须要自己去通过java把对应的对象写成转换成字节流。对于这样的通用

的操作。我们为什么不使用统一的格式呢?没错,这里就出现了java的序列化的概念。在Java的OutputStream类以下的子类ObjectOutput-

Stream类就有相应的WriteObject(Object object) 当中要求相应的object实现了java的序列化的接口。

为了更好的理解java序列化的应用。我举两个自己在开发项目中遇到的样例:

1)在使用tomcat开发JavaEE相关项目的时候。我们关闭tomcat后,对应的session中的对象就存储在了硬盘上,假设我们想要在tomcat重新启动的

时候可以从tomcat上面读取相应session中的内容,那么保存在session中的内容就必须实现相关的序列化操作。

2)假设我们使用的java对象要在分布式中使用或者在rmi远程调用的网络中使用的话,那么相关的对象必须实现java序列化接口。

亲爱的小伙伴。大概你已经了解了java序列化相关的作用。接下来们来看看怎样实现java的序列化吧。

~

 二.实现java对象的序列化和反序列化。

Java对象的序列化有两种方式。

a.是对应的对象实现了序列化接口Serializable,这个使用的比較多。对于序列化接口Serializable接口是一个空的接口,它的主要作用就是

标识这个对象时可序列化的,jre对象在传输对象的时候会进行相关的封装。这里就不做过多的介绍了。

以下是一个实现序列化接口的Java序列化的样例:很easy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.shop.domain;
 
import java.util.Date;
 
 
public class Article implements java.io.Serializable
{
    private static final long serialVersionUID
= 1L;
    private Integer
id; 
    private String
title;  
//文章标题
    private String
content;  
//
文章内容
    private String
faceIcon;
//表情图标
    private Date
postTime; 
//文章发表的时间
    private String
ipAddr;  
//用户的ip
     
    private User
author;  
//回复的用户
     
    public Integer
getId() {
        return id;
    }
    public void setId(Integer
id) {
        this.id
= id;
    }
    public String
getTitle() {
        return title;
    }
    public void setTitle(String
title) {
        this.title
= title;
    }
    public String
getContent() {
        return content;
    }
    public void setContent(String
content) {
        this.content
= content;
    }
    public String
getFaceIcon() {
        return faceIcon;
    }
    public void setFaceIcon(String
faceIcon) {
        this.faceIcon
= faceIcon;
    }
    public Date
getPostTime() {
        return postTime;
    }
    public void setPostTime(Date
postTime) {
        this.postTime
= postTime;
    }
    public User
getAuthor() {
        return author;
    }
    public void setAuthor(User
author) {
        this.author
= author;
    }
    public String
getIpAddr() {
        return ipAddr;
    }
    public void setIpAddr(String
ipAddr) {
        this.ipAddr
= ipAddr;
    }
     
     
}

  b.实现序列化的另外一种方式为实现接口Externalizable,Externlizable的部分源码例如以下:

1
2
3
4
5
6
7
8
@see java.io.ObjectInput
 @see java.io.Serializable
 @since   JDK1.1
 */
public interface Externalizable extends java.io.Serializable
{
    /**
     *
The object 
implements the
writeExternal method to save its contents
     *
by calling the methods of DataOutput 
for its
primitive values or

没错,Externlizable接口继承了java的序列化接口,并添加了两个方法:

void writeExternal(ObjectOutput out) throws IOException;

void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

首先。我们在序列化对象的时候,因为这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性能够序列化。

哪些不能够序列化,所以。对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列的时候自己主动调

用readExternal()方法,依据序列顺序挨个读取进行反序列,并自己主动封装成对象返回,然后在測试类接收,就完毕了反序列。

所以说Exterinable的是Serializable的一个扩展。

为了更好的理解相关内容,请看以下的样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package com.xiaohao.test;
 
import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
 
 
/**
 *
測试实体类
 *
@author 小浩
 *
@创建日期 2015-3-12
 */
class Person implements Externalizable{
        private static final long serialVersionUID
= 1L;<br>    String userName;
    String
password;
    String
age;
     
   
    public Person(String
userName, String password, String age) {
        super();
        this.userName
= userName;
        this.password
= password;
        this.age
= age;
    }
     
     
    public Person()
{
        super();
    }
 
 
    public String
getAge() {
        return age;
    }
    public void setAge(String
age) {
        this.age
= age;
    }
    public String
getUserName() {
        return userName;
    }
    public void setUserName(String
userName) {
        this.userName
= userName;
    }
    public String
getPassword() {
        return password;
    }
    public void setPassword(String
password) {
        this.password
= password;
    }
     
    /**
     *
序列化操作的扩展类
     */
    @Override
    public void writeExternal(ObjectOutput
out) 
throws IOException
{
        //添加一个新的对象
        Date
date=
new Date();
        out.writeObject(userName);
        out.writeObject(password);
        out.writeObject(date);
    }
     
    /**
     *
反序列化的扩展类
     */
    @Override
    public void readExternal(ObjectInput
in) 
throws IOException,
            ClassNotFoundException
{
        //注意这里的接受顺序是有限制的哦,否则的话会出错的
        //
比如上面先write的是A对象的话,那么以下先接受的也一定是A对象...
        userName=(String)
in.readObject();
        password=(String)
in.readObject();
        SimpleDateFormat
sdf=
new SimpleDateFormat("yyyy-MM-dd");
        Date
date=(Date)in.readObject();       
        System.out.println("反序列化后的日期为:"+sdf.format(date));
         
    }
    @Override
    public String
toString() {
        //注意这里的年龄是不会被序列化的,所以在反序列化的时候是读取不到数据的
        return "username:"+userName+"密
码:"
+password+"年龄:"+age;
    }
}
 
 
/**
 *
序列化和反序列化的相关操作类
 *
@author 小浩
 *
@创建日期 2015-3-12
 */
class Operate{
    /**
     *
序列化方法
     *
@throws IOException
     *
@throws FileNotFoundException
     */
    public void serializable(Person
person) 
throws FileNotFoundException,
IOException{
        ObjectOutputStream
outputStream=
new ObjectOutputStream(new FileOutputStream("a.txt"));
        outputStream.writeObject(person);      
    }
     
    /**
     *
反序列化的方法
     *
@throws IOException
     *
@throws FileNotFoundException
     *
@throws ClassNotFoundException
     */
    public Person
deSerializable() 
throws FileNotFoundException,
IOException, ClassNotFoundException{
        ObjectInputStream
ois=
new ObjectInputStream(new FileInputStream("a.txt"));
        return (Person)
ois.readObject();
    }
     
 
     
}
/**
 *
測试实体主类
 *
@author 小浩
 *
@创建日期 2015-3-12
 */
public class Test{
    public static void main(String[]
args) 
throws FileNotFoundException,
IOException, ClassNotFoundException {
       Operate
operate=
new Operate();
       Person
person=
new Person("小浩","123456","20");
       System.out.println("为序列化之前的相关数据例如以下:\n"+person.toString());
       operate.serializable(person);
       Person
newPerson=operate.deSerializable();
       System.out.println("-------------------------------------------------------");
       System.out.println("序列化之后的相关数据例如以下:\n"+newPerson.toString());
    }
     
     
}

首先,我们在序列化UserInfo对象的时候。因为这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性可

以序列化。哪些不能够序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列

的时候自己主动调用readExternal()方法,依据序列顺序挨个读取进行反序列,并自己主动封装成对象返回,然后在測试类接收。就完毕了反

序列。

***对于实现Java的序列化接口须要注意一下几点:

1.java中的序列化时transient变量(这个keyword的作用就是告知JAVA我不能够被序列化)和静态变量不会被序列

化(以下是一个測试的样例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.io.*;
 
class Student1 implements Serializable
{
    private static final long serialVersionUID
= 1L;
    private String
name;
    private transient String
password;
    private static int count
0;
 
    public Student1(String
name, String password) {
        System.out.println("调用Student的带參的构造方法");
        this.name
= name;
        this.password
= password;
        count++;
    }
 
    public String
toString() {
        return "人数:
"
 +
count + 
"
姓名: "
 +
name + 
"
password: "
 +
password;
    }
}
 
public class ObjectSerTest1
{
    public static void main(String
args[]) {
        try {
            FileOutputStream
fos = 
new FileOutputStream("test.obj");
            ObjectOutputStream
oos = 
new ObjectOutputStream(fos);
            Student1
s1 = 
new Student1("张三""12345");
            Student1
s2 = 
new Student1("王五""54321");
            oos.writeObject(s1);
            oos.writeObject(s2);
            oos.close();
            FileInputStream
fis = 
new FileInputStream("test.obj");
            ObjectInputStream
ois = 
new ObjectInputStream(fis);
            Student1
s3 = (Student1) ois.readObject();
            Student1
s4 = (Student1) ois.readObject();
            System.out.println(s3);
            System.out.println(s4);
            ois.close();
        catch (IOException
e) {
            e.printStackTrace();
        catch (ClassNotFoundException
e1) {
            e1.printStackTrace();
        }
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
 
public class Test{
 
 
     
    public static void main(String
args[]){
         
        try {
 
            FileInputStream
fis = 
new FileInputStream("test.obj");
            ObjectInputStream
ois = 
new ObjectInputStream(fis);
 
            Student1
s3 = (Student1) ois.readObject();
            Student1
s4 = (Student1) ois.readObject();
 
            System.out.println(s3);
            System.out.println(s4);
 
            ois.close();
        catch (IOException
e) {
            e.printStackTrace();
        catch (ClassNotFoundException
e1) {
            e1.printStackTrace();
        }
    }
     
     
     
}

  

2.也是最应该注意的,假设你先序列化对象A后序列化B。那么在反序列化的时候一定记着JAVA规定先读到的对象

是先被序列化的对象,不要先接收对象B,那样会报错.尤其在使用上面的Externalizable的时候一定要注意读取

的先后顺序。

3.实现序列化接口的对象并不强制声明唯一的serialVersionUID。是否声明serialVersionUID对于对象序列化的向

上向下的兼容性有非常大的影响。我们来做个測试:

思路一

把User中的serialVersionUID去掉,序列化保存。反序列化的时候,添加或降低个字段。看是否成功。

Java代码

1
2
3
4
5
6
7
8
9
10
11
public class User implements Serializable{
 
private String
name;
 
 private int age;
 
private long phone;
 
private List<UserVo>
friends;
 
...<br>}

  

保存到文件里:

1
2
3
4
5
6
7
8
9
10
11
Java代码
ByteArrayOutputStream
bos = 
new ByteArrayOutputStream();
ObjectOutputStream
os = 
new ObjectOutputStream(bos);
os.writeObject(src);
os.flush();
os.close();
byte[]
b = bos.toByteArray();
bos.close();
FileOutputStream
fos = 
new FileOutputStream(dataFile);
fos.write(b);
fos.close();

 

添加或者降低字段后,从文件里读出来,反序列化:

1
2
3
4
5
6
7
8
9
10
11
Java代码
ByteArrayOutputStream
bos = 
new ByteArrayOutputStream();
ObjectOutputStream
os = 
new ObjectOutputStream(bos);
os.writeObject(src);
os.flush();
os.close();
byte[]
b = bos.toByteArray();
bos.close();
FileOutputStream
fos = 
new FileOutputStream(dataFile);
fos.write(b);
fos.close();

  

结果:抛出异常信息

Java代码

1
2
3
4
5
6
7
8
Exception
in thread 
"main" java.io.InvalidClassException:
serialize.obj.UserVo; local 
class incompatible:
stream classdesc serialVersionUID = 
3305402508581390189,
local 
class serialVersionUID
7174371419787432394 at
java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:
560)
at
java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:
1582)
at
java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:
1495)
at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1731)
at
java.io.ObjectInputStream.readObject0(ObjectInputStream.java:
1328)
at
java.io.ObjectInputStream.readObject(ObjectInputStream.java:
350)
at
serialize.obj.ObjectSerialize.read(ObjectSerialize.java:
74)
at
serialize.obj.ObjectSerialize.main(ObjectSerialize.java:
27)

  

 
思路二

eclipse指定生成一个serialVersionUID,序列化保存。改动字段后反序列化

略去代码

结果:反序列化成功

结论

假设没有明白指定serialVersionUID。序列化的时候会依据字段和特定的算法生成一个serialVersionUID,当属性有变化时这个id发生了变化,所以反序列化的时候

就会失败。

抛出“本地classd的唯一id和流中class的唯一id不匹配”。

jdk文档关于serialVersionUID的描写叙述:

写道

假设可序列化类未显式声明 serialVersionUID,则序列化执行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。只是,强烈建议 全部可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的具体信息具有较高的敏感性,依据编译器实现的不同可能千差万别。这样在反序列化过程中可能会导致意外的
InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性。序列化类必须声明一个明白的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(假设可能),原因是这样的声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没实用处。数组类不能声明一个明白的 serialVersionUID,因此它们总是具有默认的计算值,可是数组类没有匹配 serialVersionUID
值的要求。

三.实现序列化的其他方式  (这是一个扩展内容,感兴趣的能够扩展一下)

1)是把对象包装成JSON字符串传输。

这里採用JSON格式同一时候使用採用Google的gson-2.2.2.jar 进行转义

2)採用谷歌的ProtoBuf

随着Google工具protoBuf的开源,protobuf也是个不错的选择。

对JSON,Object Serialize(Java的序列化和反序列化),

ProtoBuf 做个对照。

定义一个通用的待传输的对象UserVo:

 
1
2
3
4
5
6
7
8
public class User
<span
style=
"white-space:
pre;"
>private static final long serialVersionUID
= -5726374138698742258L;</span>
private String
name;
  private int age;
  private long phone;
  private List<User>
friends;
 ...set和get方法
 }

 

初始化User的实例src:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Java代码
User
user1 = 
new UserVo();
user1
.setName(
"user1
"
);
 user1
.setAge(
30);
 user1
.setPhone(13789126278L);
 UserVo
f1 = 
new UserVo();
 f1.setName("tmac");
 f1.setAge(32);
 f1.setPhone(123L);
 User
user2 = 
new User();
 user2
.setName(
"user2
"
);
 user2
.setAge(
29);
 user2
.setPhone(123L); <br> List<User> friends = 
new ArrayList<User>();
 friends.add(user1
);
 friends.add(user2
);
 user1
.setFriends(friends);

1.首先使用JOSN来实现序列化。

1
2
Java代码
Gson
gson = 
new Gson();<br>String
json = gson.toJson(src);

  

得到的字符串:

1
2
3
Js代码
 
{"name":"user1
"
,"age":30,"phone":123,"friends":[{"name":"user1
"
,"age":32,"phone":123},{"name":"user2
"
,"age":29,"phone":123}]}

字节数为153

Json的长处:明文结构一目了然,能够跨语言,属性的添加降低对解析端影响较小。

缺点:字节数过多,依赖于不同的第三方类库。

Object Serialize(Java的序列化和反序列化)

UserVo实现Serializalbe接口,提供唯一的版本:

序列化方法:

Java代码
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(src);
os.flush();
os.close();
byte[] b = bos.toByteArray();
bos.close();
 

字节数是238

反序列化:

Java代码
ObjectInputStream ois = new ObjectInputStream(fis);
vo = (UserVo) ois.readObject();
ois.close();
fis.close();

Object Serializalbe 长处:java原生支持,不须要提供第三方的类库,使用比較简单。

缺点:无法跨语言。字节数占用比較大,某些情况下对于对象属性的变化比較敏感。

对象在进行序列化和反序列化的时候,必须实现Serializable接口,但并不强制声明唯一的serialVersionUID

是否声明serialVersionUID对于对象序列化的向上向下的兼容性有非常大的影响。

Google ProtoBuf

protocol buffers 是google内部得一种传输协议,眼下项目已经开源(http://code.google.com/p/protobuf/)。

它定义了一种紧凑得可扩展得二进制协议格式。适合网络传输,而且针对多个语言有不同得版本号可供选择。

以protobuf-2.5.0rc1为例,准备工作:

下载源代码,解压,编译。安装

Shell代码
tar zxvf protobuf-2.5.0rc1.tar.gz ./configure ./make ./make install

測试:

Shell代码
MacBook-Air:~ ming$ protoc --version libprotoc 2.5.0

成功安装!

进入源代码得java文件夹,用mvn工具编译生成所需得jar包,protobuf-java-2.5.0rc1.jar

1、编写.proto文件,命名UserVo.proto

1
2
3
4
5
6
7
8
9
10
11
12
Text代码
 
package serialize;
option
java_package = 
"serialize";
option
java_outer_classname=
"UserVoProtos";
message
User{
optional
string name = 
1;
optional
int32 age = 
2;
optional
int64 phone = 
3;
repeated
serialize.UserVo friends = 
4;
 
}

  

2、在命令行利用protoc 工具生成builder类

Shell代码
protoc -IPATH=.proto文件所在得文件夹 --java_out=java文件的输出路径  .proto的名称

得到UserProtos类

3、编写序列化代码

1
2
3
4
5
6
7
8
9
10
11
12
Java代码
 
UserVoProtos.User.Builder
builder = UserVoProtos.User.newBuilder();
builder.setName("Yaoming");
builder.setAge(
30);
builder.setPhone(13789878978L);
UserVoProtos.UserVo.Builder
builder1 = UserVoProtos.UserVo.newBuilder();
builder1.setName("tmac");
builder1.setAge(
32);
builder1.setPhone(138999898989L);
UserVoProtos.UserVo.Builder
builder2 = UserVoProtos.UserVo.newBuilder();
builder2.setName("liuwei");
builder2.setAge(
29);
builder2.setPhone(138999899989L);
builder.addFriends(builder1);
builder.addFriends(builder2);
UserVoProtos.UserVo
vo = builder.build();  
byte[]
v = vo.toByteArray();

  

字节数53

反序列化

1
2
3
Java代码
UserVoProtos.UserVo
uvo = UserVoProtos.UserVo.parseFrom(dstb);
System.out.println(uvo.getFriends(0).getName());

 

结果:tmac,反序列化成功

google protobuf 长处:字节数非常小,适合网络传输节省io。跨语言 。

缺点:须要依赖于工具生成代码。

工作机制

proto文件是对数据的一个描写叙述,包含字段名称,类型,字节中的位置。

protoc工具读取proto文件生成相应builder代码的类库。protoc xxxxx  --java_out=xxxxxx 生成java类库。builder类依据自己的算法把数据序列化成字节流,或者把字节流依据反射的原理反序列化成对象。

官方的演示样例:https://developers.google.com/protocol-buffers/docs/javatutorial。

proto文件里的字段类型和java中的相应关系:

详见:https://developers.google.com/protocol-buffers/docs/proto

.proto Type java Type c++ Type
double double double
float float float
int32 int int32
int64 long int64
uint32 int uint32
unint64 long uint64
sint32 int int32
sint64 long int64
fixed32 int uint32
fixed64 long uint64
sfixed32 int int32
sfixed64 long int64
bool boolean bool
string String string
bytes byte string
字段属性的描写叙述:
写道
required: a well-formed message must have exactly one of this field. optional: a well-formed message can have zero or one of this field (but not more than one). repeated: this field can be repeated any number of times (including zero) in a well-formed message.
The order of the repeated values will be preserved.
protobuf 在序列化和反序列化的时候,是依赖于.proto文件生成的builder类完毕。字段的变化假设不表如今.proto文件里就不会影响反序列化,比較适合字段变化的情况。

做个測试:把UserVo序列化到文件里:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Java代码
UserProtos.User
vo = builder.build();
byte[]
v = vo.toByteArray();
FileOutputStream
fos = 
new FileOutputStream(dataFile);
fos.write(vo.toByteArray());
fos.close();
  
 
为User添加字段,相应的.proto文件:
 
Text代码
 
package serialize;
option
java_package = 
"serialize";
option
java_outer_classname=
"UserVoProtos";
message
User{
optional
string name = 
1;
optional
int32 age = 
2;
optional
int64 phone = 
3;
repeated
serialize.UserVo friends = 
4;
optional
string address = 
5;
}
 
   
 
从文件里反序列化回来:
 
Java代码
FileInputStream
fis = 
new FileInputStream(dataFile);
byte[]
dstb = 
new byte[fis.available()];
for(int i=0;i<dstb.length;i++){
dstb[i] = (
byte)fis.read();
}
fis.close();
UserProtos.User uvo = UserProtos.User.parseFrom(dstb);
System.out.println(uvo.getFriends(0).getName());

成功得到结果。

三种方式对照传输相同的数据,google protobuf仅仅有53个字节是最少的。结论:
 
方式 长处 缺点
JSON

跨语言、格式清晰一目了然

字节数比較大,须要第三方类库
Object Serialize java原生方法不依赖外部类库 字节数比較大,不能跨语言
Google protobuf

跨语言、字节数比較少

编写.proto配置用protoc工具生成相应的代码

Java序列化的几种方式的更多相关文章

  1. Java序列化的几种方式以及序列化的作用

    Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象 ...

  2. 面试阿里,字节跳动,华为必须知道的Java创建对象的5种方式

    Java创建对象的5种方式 1.直接new,调用了构造器2.通过clone(),没有调用构造器3.通过反射,调用了构造器4.通过反序列化,没有调用构造器5.通过Unsafe类的allocateInst ...

  3. Java创建对象的4种方式?

     [Java创建对象的4种方式?] 1)通过new语句实例化一个对象 2)通过反射机制创建对象 3)通过clone()方法创建一个对象  (复制) 4)通过反序列化方式创建对象

  4. Java创建对象的几种方式

    解析:Java创建对象的几种方式(重要):(1) 用new语句创建对象,这是最常见的创建对象的方法.(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Co ...

  5. &和&&的共同点和区别、Java字符含义和Java创建对象的几种方式

    一.&和&&的共同点和区别 1.&和&&的联系(共同点): &和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定. 操 ...

  6. Java创建对象的几种方式。

    Java创建对象的几种方式(重要): (1) 用new语句创建对象,这是最常见的创建对象的方法. (2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Con ...

  7. 使用Maven运行Java main的3种方式

    使用Maven运行Java main的3种方式 原文  http://blog.csdn.net/qbg19881206/article/details/19850857 主题 Maven maven ...

  8. DRF 序列化组件 序列化的两种方式 反序列化 反序列化的校验

    序列化组件 django自带的有序列化组件不过不可控不建议使用(了解) from django.core import serializers class Books(APIView): def ge ...

  9. K:java中序列化的两种方式—Serializable或Externalizable

    在java中,对一个对象进行序列化操作,其有如下两种方式: 第一种: 通过实现java.io.Serializable接口,该接口是一个标志接口,其没有任何抽象方法需要进行重写,实现了Serializ ...

随机推荐

  1. [CF911A]Nearest Minimums

    题目大意: 给你一个数列,问数列中最小数的最近距离. 思路: 直接模拟即可. #include<cstdio> #include<cctype> #include<alg ...

  2. 使用apt-cache search搜索想要的软件包

    环境: Ubuntu14.10 我在编译u-boot代码的时候遇到了如下问题: LD test/dm/built-in.o CC examples/standalone/stubs.o LD exam ...

  3. xargs: How To Control and Use Command Line Arguments

    参考: http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/ http://linux ...

  4. ZooKeeper本身是一个分布式应用程序,为写入分布式应用程序提供服务。

    ZooKeeper本身是一个分布式应用程序,为写入分布式应用程序提供服务. 作为ZooKeeper架构的一部分的每个组件在下表中进行了说明. 部分 描述 Client(客户端) 客户端,我们的分布式应 ...

  5. MySql优化--使用索引优化

    原文:http://blog.csdn.net/zuoanyinxiang/article/details/50606837 1.索引优化的原理   在没有使用索引的时候,数据库系统会根据要查找的值到 ...

  6. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:3.安装Oracle RAC-3.2.安装 cvuqdisk 软件包

    3.2.安装 cvuqdisk 软件包 3.2.1. 准备Oracle  Grid安装包 上传Grid .Oracle 安装文件: sftp> put E:\Software\linux.x64 ...

  7. javascript快速入门4--函数与内置对象

    函数 函数(又称为方法)用于对一大段为了达到某种目的的代码进行归类,以使代码更具有条理: //一段计算三角形面积的代码 var wide=window.prompt("请输入三角形的底边长度 ...

  8. (转)Vue.use源码分析

    我想有过vue开发经验的,对于vue.use并不陌生.当使用vue-resource或vue-router等全局组件时,必须通过Vue.use方法引入,才起作用.那么vue.use在组件引入之前到底做 ...

  9. [转] Google 开源 iOS 应用测试工具:EarlGrey

    Google 开源 iOS 应用测试工具:EarlGrey oschina 发布于: 2016年02月18日 (3评) 分享到:    收藏 +53 3月19日,深圳源创会火热报名中,go>&g ...

  10. wine 魔兽争霸

    连接参见http://linux-wiki.cn/wiki/%E7%94%A8Wine%E8%BF%90%E8%A1%8C%E9%AD%94%E5%85%BD%E4%BA%89%E9%9C%B8III ...