序列化和反序列化(二)——Serializable 接口

男娘i 2022-02-15 13:41 396阅读 0赞

Serializable 接口**:**该接口没有方法或字段,仅用于标识由该接口实现类创建的对象是可序列化的。

  1. 示例:
  2. import java.io.Serializable;
  3. public class UserInfo implements Serializable {
  4. private static final long serialVersionUID = -564040236692883153L;
  5. private int age;
  6. private String name;
  7. public int getAge() {
  8. return age;
  9. }
  10. public void setAge(int age) {
  11. this.age = age;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. @Override
  20. public String toString() {
  21. return "name='" + name + '\'' + ", age=" + age;
  22. }
  23. }
  24. import java.io.*;
  25. public class Test {
  26. /**
  27. * 序列化
  28. *
  29. * @author GaoHuanjie
  30. */
  31. public static void serialize(){
  32. UserInfo userInfo = new UserInfo();
  33. userInfo.setAge(23);
  34. userInfo.setName("Tom");
  35. System.out.println(userInfo);
  36. ObjectOutput objectOutput = null;
  37. try {
  38. objectOutput = new ObjectOutputStream(new FileOutputStream("D:\\user_info.ser"));
  39. objectOutput.writeObject(userInfo);
  40. objectOutput.flush();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. } finally {
  44. if (objectOutput!=null) {
  45. try {
  46. objectOutput.close();
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. }
  52. }
  53. /**
  54. * 反序列化
  55. *
  56. * @author GaoHuanjie
  57. */
  58. public static void deserialize(){
  59. ObjectInput objectInput = null;
  60. try {
  61. objectInput = new ObjectInputStream(new FileInputStream("D:\\user_info.ser"));
  62. UserInfo userInfo = (UserInfo) objectInput.readObject();
  63. System.out.println(userInfo);
  64. } catch (Exception e) {
  65. e.printStackTrace();
  66. } finally {
  67. if (objectInput!=null) {
  68. try {
  69. objectInput.close();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. }
  75. }
  76. public static void main(String[] args) {
  77. serialize();//序列化
  78. deserialize();//反序列化
  79. }
  80. }

serialVersionUID**常量**

  1. 实现Serializable接口的类须显式声明serialVersionUID常量,该常量作用如下:反序列化能否成功取决于三方面,首先序列化和反序列化类所在包相同,其次序列化和反序列化类的类名相同,最后序列化和反序列化类serialVersionUID的值要相同,两个类中的代码可以不同,如果不指定serialVersionUID,则类出现警告,但这是次要的,更重要的是序列化时将根据JavaTM)对象序列化规范为该类计算一个默认的serialVersionUID值,这就要求反序列化时使用的类与序列化时使用的类必须完全相同(有相同的属性和方法),否则反序列化失败,因为反序列化时serialVersionUID的值也是根据JavaTM)对象序列化规范计算出来的默认值,由于序列化类代码和反序列化类代码不同,则serialVersionUID的值肯定不同;但在实际开发中序列化类代码和反序列化类代码极有可能不同,在这种情况下为了反序列化成功就要求显式声明serialVersionUID常量且值要相同。serialVersionUID的生成策略有两种:一个是固定的 1L,一个是根据JavaTM)对象序列化规范生成的 long 类型数据;如果没有特殊需求,推荐使用固定值,这样便于序列化类代码和反序列化类serialVersionUID一致;如果限制某些用户的使用,则推荐第二种生成策略。

transient 关键字

  1. 在序列化时,transient 关键字修饰的成员变量不会被序列化;在反序列化时,transient 关键字修饰的成员变量被赋以默认值,如整型为0,浮点型为0.0,引用类型为null

static**关键字**

  1. 在序列化时,static关键字修饰的成员变量不会被序列化。序列化保存的是对象的状态,静态变量属于类的状态,因此序列化并不保存静态变量,即序列化信息中不包含这个静态成员域。
  2. import java.io.Serializable;
  3. public class UserInfo implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. private static int count;
  6. public UserInfo() {
  7. count++;
  8. }
  9. public String toString() {
  10. return "count:" + count;
  11. }
  12. }
  13. static修饰的成员变量,序列化和反序列化代码在一个进程中执行时会序列化成功,因为序列化时jvm已经把静态变量加载进来了,所以反序列化时获取的是加载好的静态变量,如下例子:
  14. import java.io.*;
  15. public class Test {
  16. public static void main(String[] args) {
  17. try {
  18. ObjectOutput objectOutput = new ObjectOutputStream(new FileOutputStream("user_info.ser"));
  19. objectOutput.writeObject(new UserInfo());
  20. objectOutput.close();
  21. ObjectInput objectInput = new ObjectInputStream(new FileInputStream("user_info.ser"));
  22. UserInfo userInfo = (UserInfo) objectInput.readObject();
  23. System.out.println(userInfo);
  24. objectInput.close();
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30. static修饰的成员变量,序列化和反序列化代码不再一个进程,由于反序列化时是重新加载静态变量,所以静态变量是初始值,如下列子:
  31. 序列化:
  32. import java.io.*;
  33. public class Test1 {
  34. public static void main(String[] args) {
  35. try {
  36. ObjectOutput objectOutput = new ObjectOutputStream(new FileOutputStream("user_info.ser"));
  37. objectOutput.writeObject(new UserInfo());
  38. objectOutput.close();
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. 反序列化:
  45. import java.io.*;
  46. public class Test2 {
  47. public static void main(String[] args) {
  48. try {
  49. ObjectInput objectInput = new ObjectInputStream(new FileInputStream("user_info.ser"));
  50. UserInfo userInfo = (UserInfo) objectInput.readObject();
  51. System.out.println(userInfo);
  52. objectInput.close();
  53. } catch (Exception e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. }

发表评论

表情:
评论列表 (有 0 条评论,396人围观)

还没有评论,来说两句吧...

相关阅读