歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java的序列化機制原理分析

Java的序列化機制原理分析

日期:2017/3/1 10:21:01   编辑:Linux編程

Java的序列化機制原理分析,我們查看下ObjectOutputStream的writeObject方法

  1. //final方法,不允許子類覆蓋
  2. public final void writeObject(Object obj) throws IOException {
  3. if (enableOverride) { //如果開啟允許序列化被重寫
  4. writeObjectOverride(obj); //調用子類的序列化重寫方法
  5. return;
  6. }
  7. try {
  8. writeObject0(obj, false);//調用默認的序列化過程
  9. } catch (IOException ex) {
  10. if (depth == 0) {
  11. writeFatalException(ex);
  12. }
  13. throw ex;
  14. }
  15. }

如果要自定義這個序列化過程,則可以寫一個子類,集成ObjectOutputStream,然後覆蓋其兩個方法

  1. protected ObjectOutputStream() throws IOException, SecurityException {
  2. SecurityManager sm = System.getSecurityManager();
  3. if (sm != null) {
  4. sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
  5. }
  6. bout = null;
  7. handles = null;
  8. subs = null;
  9. enableOverride = true;
  10. debugInfoStack = null;
  11. }
  12. protected void writeObjectOverride(Object obj) throws IOException {
  13. }

我們再看下具體的writeObject0方法:

  1. private void writeObject0(Object obj, boolean unshared)
  2. throws IOException
  3. {
  4. boolean oldMode = bout.setBlockDataMode(false);
  5. depth++;
  6. try {
  7. // 先對obj實例的類信息進行序列化,
  8. int h;
  9. if ((obj = subs.lookup(obj)) == null) {
  10. writeNull();
  11. return;
  12. } else if (!unshared && (h = handles.lookup(obj)) != -1) {//可以自定義class類信息的序列化handler
  13. writeHandle(h);
  14. return;
  15. } else if (obj instanceof Class) { //類信息序列化
  16. writeClass((Class) obj, unshared);
  17. return;
  18. } else if (obj instanceof ObjectStreamClass) { //類信息序列化,此時還包括serialVersionUID
  19. writeClassDesc((ObjectStreamClass) obj, unshared);
  20. return;
  21. }
  22. // check for replacement object
  23. //這裡還可以對序列化的類進行替換序列化
  24. Object orig = obj;
  25. Class cl = obj.getClass();
  26. ObjectStreamClass desc;
  27. for (;;) {
  28. // REMIND: skip this check for strings/arrays?
  29. Class repCl;
  30. desc = ObjectStreamClass.lookup(cl, true);
  31. if (!desc.hasWriteReplaceMethod() ||
  32. (obj = desc.invokeWriteReplace(obj)) == null ||
  33. (repCl = obj.getClass()) == cl)
  34. {
  35. break;
  36. }
  37. cl = repCl;
  38. }
  39. if (enableReplace) {
  40. Object rep = replaceObject(obj);
  41. if (rep != obj && rep != null) {
  42. cl = rep.getClass();
  43. desc = ObjectStreamClass.lookup(cl, true);
  44. }
  45. obj = rep;
  46. }
  47. // if object replaced, run through original checks a second time
  48. //如果類信息被替換過,則需要進行第二次處理
  49. if (obj != orig) {
  50. subs.assign(orig, obj);
  51. if (obj == null) {
  52. writeNull();
  53. return;
  54. } else if (!unshared && (h = handles.lookup(obj)) != -1) {
  55. writeHandle(h);
  56. return;
  57. } else if (obj instanceof Class) {
  58. writeClass((Class) obj, unshared);
  59. return;
  60. } else if (obj instanceof ObjectStreamClass) {
  61. writeClassDesc((ObjectStreamClass) obj, unshared);
  62. return;
  63. }
  64. }
  65. // remaining cases
  66. //寫入類實例對象的數據,第一次總是在此執行
  67. if (obj instanceof String) {
  68. writeString((String) obj, unshared);
  69. } else if (cl.isArray()) {
  70. writeArray(obj, desc, unshared);
  71. } else if (obj instanceof Enum) {
  72. writeEnum((Enum) obj, desc, unshared);
  73. } else if (obj instanceof Serializable) { //我們的bean需要實現Serializable接口,才能進行序列化
  74. writeOrdinaryObject(obj, desc, unshared);
  75. } else {
  76. if (extendedDebugInfo) {
  77. throw new NotSerializableException(
  78. cl.getName() + "\n" + debugInfoStack.toString());
  79. } else {
  80. throw new NotSerializableException(cl.getName());
  81. }
  82. }
  83. } finally {
  84. depth--;
  85. bout.setBlockDataMode(oldMode);
  86. }
  87. }
Copyright © Linux教程網 All Rights Reserved