Java--编码集与序列化

一、编码问题

Java中数据类型如下图
Java--编码集与序列化_第1张图片
如下代码的注释部分做了详细的说明:

public class EncodeTest {
    public static void main(String[] args) throws Exception {
        String str = "长城wall";
        byte[] byte1 = str.getBytes();// 将字符串转换成字节序列用的是编译器默认的编码方式gbk
        for (byte b : byte1){
            // 把字节转换成int,以16进制的方式显示
            //System.out.print(Integer.toHexString(b) + " ");
            System.out.print(Integer.toHexString(b & 0xff) + "  ");// 把byte转换为int就是把后8位前面添加24个0,因此加上位运算可以将前面的24个0不以16进制的形式显示
        }
        System.out.println();

        // gbk编码中文占用两个字节,编码英文占用1个字节
        byte[] byte2 = str.getBytes("gbk");
        for (byte b : byte2){
            System.out.print(Integer.toHexString(b & 0xff) + "  ");
        }
        System.out.println();

        // utf-8编码中文占用3个字节,编码英文占用1个字节
        byte[] byte3 = str.getBytes("utf-8");
        for (byte b : byte3){
            System.out.print(Integer.toHexString(b & 0xff) + "  ");
        }
        System.out.println();

        // java是双字节编码 utf-16be编码,中文英文都占用两个字节
        byte[] byte4 = str.getBytes("utf-16be");
        for (byte b : byte4){
            System.out.print(Integer.toHexString(b & 0xff) + "  ");
        }
        System.out.println();

        /** * 当字节序列是以什么方式编码时,想把字节序列变换成字符串,则也需要使用该种编码方式进行编码 */
// String str1 = new String(byte4);// 采用默认的方式gbk编码,此时与该字节序列开始的utf-16be方式不同,故会乱码
// System.out.println(str1);
        String str1 = new String(byte4, "utf-16be");
        System.out.println(str1);

        /** * 文本文件 就是字节序列 * 可以使任意编码的字节序列 * 如果在中文机器上直接创建的文本文件,那么该文本文件就只认识ansi编码(在中文机器中ansi编码代表gbk) */
    }
}

小结:
1. gbk编码中文占用2个字节,编码英文占用1个字节;
2. utf-8编码中文占用3个字节,编码英文占用1个字节;
3. java是utf-16be编码(双字节编码),中文英文都占用两个字节

二、序列化与反序列化

这里只是简单谈谈“序列化与反序列化”

1. 定义:对象序列化就是将Object对象转换成byte序列,反之叫对象的反序列化
2. 作用:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中; 在网络上传送对象的字节序列。
3. 序列化流(ObjectOutputStream)是过滤流—writeObject
反序列化流(ObjectInputStream)–readObject
4. 序列化接口(Serializable):对象必须实现序列化接口,才能进行序列化,否则将出现异常,这个接口没有任何方法,只是一个标准
5. transient关键字:加了transient关键字的元素不会被jvm默认的序列化,但是该元素可以自己单独完成序列化。Transient是为了提高性能,比如说在网络传输中有些数据无效就不必序列化了传输,节省流量。对于加了transient关键字的元素,需要序列化时通过writeObject和readObject方法

private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException{
        s.defaultWriteObject();// 将jvm默认的序列化的元素序列化
        s.writeInt(stuage);// 将自己单独序列化的元素序列化
    }
    private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();// 将jvm默认反序列化的元素反序列化
        this.stuage = s.readInt();// 将自己单独反序列化的元素反序列化
    }

6 . 一个类实现了序列化接口,其子类都可以进行序列化。对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,那么其父类的构造函数就会被显示调用,如果其父类实现了序列化接口,其父类的构造函数就不会被调用【一层层向上,只要没被序列化的父类都会被显示调用】。
7. 异常“java.io.InvalidClassException”,是因为得先序列化再反序列化。
http://www.blogjava.net/fingki/archive/2009/01/13/251100.html

你可能感兴趣的:(Java--编码集与序列化)