[转载] Java序列化的几种方式以及序列化的作用

参考链接: Java中带有继承的对象序列化

文章转载自:  本文着重讲解一下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序列化的例子:非常简单

 

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的部分源代码如下: 

* @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 

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

 

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

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

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

 

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

 

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+"密 码:"+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变量(这个关键字的作用就是告知JAVA我不可以被序列化)和静态变量不会被序列

 

          化(下面是一个测试的例子)

 

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;

    }

}

 

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();

        }

    }

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代码 

public class User implements Serializable{

 

private String name;

 

 private int age;

 

private long phone;

 

private List<UserVo> friends;

 

...<br>} 

保存到文件中: 

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代码

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代码 

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:

 

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: 

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来实现序列化。 

Gson gson = new Gson();<br>String json = gson.toJson(src); 

得到的字符串: 

{"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接口,提供唯一的版本号:  序列化方法: 

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ObjectOutputStream os = new ObjectOutputStream(bos);

os.writeObject(src);

os.flush();

os.close();

byte[] b = bos.toByteArray();

bos.close(); 

字节数是238 

反序列化: 

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 

 

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、编写序列化代码 

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  反序列化 

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序列化到文件中: 

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()); 

从文件中反序列化回来: 

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工具生成对应的代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540264.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx 非80、443端口跳转到80、443

其实很简单: 123if ($server_port ! 80 ) { rewrite ^/(.*)$ http://$host/$1 permanent; }举一反三。。。 123if ($server_port ! 443 ) { rewrite ^/(.*)$ https://$host/$1 permanent; }123if ($host ! host ) { rewrite ^/(.*)$ http://host/$1 permanent; }本文转自 ninny…

[转载] 一文彻底搞懂父类引用指向子类对象问题

参考链接&#xff1a; 用子类引用子类对象 vs 父类引用 public class Father { private String name; private int age; private int weight; public void eat() { System.out.println("Father is eating"); } private void run() { System.out.println("Runin…

把控站外seo效果的几个操作点

把控站外seo效果的几个操作点 实际上&#xff0c;站外的seo不仅仅是外链这么简单&#xff0c;还包括用户行为&#xff08;点击&#xff09;&#xff0c;品牌词曝光等工作。大部分情况下&#xff0c;我们所说的站外优化就是发外链。本文就外链相关事宜&#xff0c;讲解些许操作点…

[转载] 【C语言】fopen C4996错误解决

参考链接&#xff1a; C和C#重载可以与继承一起使用吗 C4996 fopen: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 解决方案&#xff1a;添加宏定…

Quartus II 8.1 详解--有图---图片详解 【1讲】

Quartus II 8.1 详解--有图---图片详解 看图片比较清楚&#xff0c;比文章清楚的多 本文转自 zhangguangyi 51CTO博客&#xff0c;原文链接http://blog.51cto.com/bosszhang/808019:

[转载] JAVA数组实现学生成绩统计

参考链接&#xff1a; Java程序的输出 20(继承) 一、项目名称 数组实现学生成绩统计 二、项目描述 1.项目简介&#xff1a; 由用户输入学生人数与名字&#xff0c;并定义当前学期课程数与课程名&#xff0c;并分别录入每位学生每门课程成绩&#xff0c;系统显示输入每位学生每…

建立同步文件的脚本

为避免一个一个的去修改每一个服务器的配置文件&#xff0c;只需要rsync同步一下就可以搞定#!/bin/bash#rsync.shLOCAL_DIR"/opt/admin"test -n "$hosts" || hosts"xxxx xxxx"REMOTE_DIR"/opt/"RSYNC_LOG"/opt/var/log/rsync.log…

[转载] Java三元运算符示例

参考链接&#xff1a; Java中的运算符 本示例说明如何编写Java三元运算符。 这是语法 condition ? get_this_if_true : get_this_if_false Java三元运算符语法 (n > 18) ? true : false; (n true) ? 1 : 0; (n null) ? n.getValue() : 0; 1. Java三元运算符 …

shell下的进度条和最大最小平均值

进度条 C语言下的进度条参考我原来的一篇blog->进度条 1234567891011121314151617181920212223function proc() {i0 str arr(| / - \\) index0 while [ $i -le 100 ] do printf "[%-101s][%d%%][%c]\r" "$str" "$i" "${arr[$index]}&qu…

[转载] 你真的会用 Java 中的三目运算符吗

参考链接&#xff1a; Java中的按位运算符 转载:http://blog.jobbole.com/93511/ 写在前面&#xff1a; 三目运算符是我们经常在代码中使用的&#xff0c;a (bnull?0:1); 这样一行代码可以代替一个 if-else&#xff0c;可以使代码变得清爽易读。但是&#xff0c;三目运算符也…

HTTP Keep-Alive模式

1、什么是Keep-Alive模式&#xff1f; 我们知道HTTP协议采用“请求-应答”模式&#xff0c;当使用普通模式&#xff0c;即非KeepAlive模式时&#xff0c;每个请求/应答客户和服务器都要新建一个连接&#xff0c;完成 之后立即断开连接&#xff08;HTTP协议为无连接的协议&#…

[转载] java:比较运算符

参考链接&#xff1a; Java中的new运算符 1.compareTo()方法: compareTo()方法返回的是一个int类型值. //声明的值 BigDecimal t_sell1 new BigDecimal(); BigDecimal t_sell2 new BigDecimal(); if(t_sell1.compareTo(t_sell2)0){ return "t_sell1的值等于t_sell2&…

[转载] java左移右移和无符号右移

参考链接&#xff1a; Java中的按位右移运算符 ###知识点 java的三种位移运算符&#xff1a; <<&#xff1a;左移运算符&#xff0c;num << 1,相当于num乘以2 >>&#xff1a;右移运算符&#xff0c;num >> 1,相当于num除以2 >>>&#xff1a…

Script:List OBJECT DEPENDENT

以下脚本用以列出数据库中对象的依赖性:select D_OBJ#, 本文转自maclean_007 51CTO博客&#xff0c;原文链接: http://blog.51cto.com/maclean/1276767

[转载] java避免空指针异常_第1部分:在现代Java应用程序中避免空指针异常

参考链接&#xff1a; Java的instanceof及其应用 java避免空指针异常 空做与不做 (Null do’s and don’ts) In the talk Null References: The Billion Dollar Mistake, Sir Tony Hoare describes implementing null references as a part of the ALGOL programming languag…

[转载] 什么是Java中的自动拆装箱 integer

参考链接&#xff1a; Java中autoboxing自动装箱整数对象的比较 本文主要介绍Java中的自动拆箱与自动装箱的有关知识。 1、基本数据类型 基本类型&#xff0c;或者叫做内置类型&#xff0c;是Java中不同于类(Class)的特殊类型。它们是我们编程中使用最频繁的类型。 Jav…

[转载] python常用库

参考链接&#xff1a; Python–新一代语言 转载至&#xff1a;https://www.cnblogs.com/jiangchunsheng/p/9275881.html 今天我将介绍20个属于我常用工具的Python库&#xff0c;我相信你看完之后也会觉得离不开它们。他们是&#xff1a; Requests.Kenneth Reitz写的最富盛…

linux下安装配置oracle

检查系统是否已安装所需的开发包 使用rpm -qa命令&#xff0c;确保以下包已成功安装。对于包的版本,只有版本高于下面的都可以,如果低于此版本,则要升级处理,如下: binutils-2.15.92.0.2-13.EL4 compat-db-4.1.25-9 compat-libstdc-296-2.96-132.7.2 control-center-2.8.0-12 g…

[转载] c++多态与java多态性_Java中的多态性

参考链接&#xff1a; Java中的加法和串联 c多态与java多态性 Polymorphism is one of the core concepts of OOPS paradigm. The meaning of polymorphism is the condition of occurring in several different forms. 多态是OOPS范式的核心概念之一。 多态性的含义是以几种不…

USB peripherals can turn against their users

Turning USB peripherals into BadUSB USB devices are connected to – and in many cases even built into – virtually all computers. The interface standard conquered the world over the past two decades thanks to its versatility: Almost any computer peripheral…