java.io.NotSerializableException 两种解决方案:一是针对自己定义类解决方案,二是针对远程调用第三方类解决方案。

本文章转载自:https://examples.javacodegeeks.com/java-basics/exceptions/java-io-notserializableexception-how-to-solve-not-serializable-exception/

About Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a PhD student at the Department of Computer Science at the University of Toronto. His main interests include distributed systems, storage systems, file systems, and operating systems.

  

java.io.NotSerializableException – How to solve Not Serializable Exception

Posted by: Sotirios-Efstathios Maneas in exceptions June 10th, 2014

In this tutorial we will discuss about NotSerializableException in Java. The exception is thrown when an instance of a class must implement theSerializable interface. The exception is thrown by either the serialization runtime, or by the instance of the class. The argument of theNotSerializableException is the name of the class.

The NotSerializableException class extends the ObjectStreamExceptionclass, which is defined as the superclass of all exceptions specific to Object Stream classes. Also, the ObjectStreamException class extends theIOException which signals that an I/O exception has occurred.

Finally, the NotSerializableException exists since the 1.1 version of the Java Development Kit (JDK).

The Structure of NotSerializableException

Constructors

  • NotSerializableException()

    Creates an instance of the NotSerializableException class.

  • NotSerializableException(String s)

    Creates an instance of the NotSerializableException class, using the specified string as message. The string argument indicates the name of the class that threw the error.

The NotSerializableException in Java

To begin with, the NotSerializableException can be thrown when a class does not implement the Serializable interface. A sample example is described below:

Pair.java:

01 public class Pair {
02     /**
03      * The key (left) part of the pair.
04      */
05     private K key;
06      
07     /**
08      * The value (right) part of the pair.
09      */
10     private V value;
11      
12     public Pair(K key, V value) {
13         this.key = key;
14         this.value = value;
15     }
16      
17     /**
18      *
19      * @return, the pair's key.
20      */
21     public K getKey() {
22         return this.key;
23     }
24      
25     /**
26      *
27      * @return, the pair's value.
28      */
29     public V getValue() {
30         return this.value;
31     }
32      
33     /**
34      * Tests if an instance of the Pair class is equal to a specified Object.
35      */
36     @Override
37     public boolean equals(Object o) {
38         if(o instanceof Pair) {
39             Pair pair = (Pair) o;
40             return (this.key == pair.key && this.value == pair.value);
41         }
42         else
43             return false;
44     }
45      
46     /**
47      * Creates a String representation of the Pair class.
48      */
49     @Override
50     public String toString() {
51         return "Pair: ";
52     }
53 }

In this file, we defined the Pair class, as a Java template, which consists of two fields, key and value. Also, we defined the following methods:

  • K getKey()

    Returns the key of the pair.

  • V getValue()

    Returns the value of the pair.

  • boolean equals(Object o)

    Checks whether the specified object equals to this pair.

  • String toString()

    Returns a String representation of the Pair class.

Serializer.java:

01 import java.io.ByteArrayInputStream;
02 import java.io.ByteArrayOutputStream;
03 import java.io.IOException;
04 import java.io.ObjectInput;
05 import java.io.ObjectInputStream;
06 import java.io.ObjectOutput;
07 import java.io.ObjectOutputStream;
08  
09 public final class Serializer {
10     /**
11      * Converts an Object to a byte array.
12      *
13      * @param object, the Object to serialize.
14      * @return, the byte array that stores the serialized object.
15      */
16     public static  byte[] serialize(T object) {
17  
18         ByteArrayOutputStream bos = new ByteArrayOutputStream();
19         ObjectOutput out = null;
20         try {
21             out = new ObjectOutputStream(bos);
22             out.writeObject(object);
23  
24             byte[] byteArray = bos.toByteArray();
25             return byteArray;
26  
27         catch (IOException e) {
28             e.printStackTrace();
29             return null;
30  
31         finally {
32             try {
33                 if (out != null)
34                     out.close();
35             catch (IOException ex) {
36             }
37             try {
38                 bos.close();
39             catch (IOException ex) {
40             }
41         }
42  
43     }
44  
45     /**
46      * Converts a byte array to an Object.
47      *
48      * @param byteArray, a byte array that represents a serialized Object.
49      * @return, an instance of the Object class.
50      */
51     public static Object deserialize(byte[] byteArray) {
52         ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
53         ObjectInput in = null;
54         try {
55             in = new ObjectInputStream(bis);
56             Object o = in.readObject();
57             return o;
58  
59         catch (ClassNotFoundException | IOException e) {
60             e.printStackTrace();
61             return null;
62         finally {
63             try {
64                 bis.close();
65             catch (IOException ex) {
66             }
67             try {
68                 if (in != null)
69                     in.close();
70             catch (IOException ex) {
71             }
72         }
73     }
74 }

In this file, we defined the Serializer class, which contains the following two static methods:

  • static byte[] serialize(T object)

    Serializes the specified object in a byte array.

  • static Object deserialize(byte[] byteArray)

    Deserializes the specified byte array to an instance of the Object class.

NotSerializableExceptionExample.java:

1 public class NotSerializableExceptionExample {
2     public static void main(String[] args) {
3         Pair pair = new Pair("Key1"1);
4          
5         System.out.println("Trying to serialize the following object: " + pair);
6         Serializer.serialize(pair); // This statement throws a NotSerializableException
7     }
8 }

In this file, we defined the main method of our application that aims to serialize an instance of the Pair class. However, thePair class does not implement the Serializable interface and thus, the NotSerializableException is thrown.

A sample execution is shown below:

1 Trying to serialize the following object: Pair:
2 java.io.NotSerializableException: main.java.Pair
3     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
4     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
5     at main.java.Serializer.serialize(Serializer.java:24)
6     at main.java.NotSerializableExceptionExample.main(NotSerializableExceptionExample.java:8)

Also, the NotSerializableException can be thrown when a class that implements the Serializable interface contains fields that are not serializable:

SerializableClass.java:

01 import java.io.Serializable;
02  
03 public class SerializableClass implements Serializable {
04     private static final long serialVersionUID = 1420672609912364060L;
05     private Pair pair = null;
06      
07     public SerializableClass(String key, Integer value) {
08         this.pair = new Pair(key, value);
09     }
10      
11     @Override
12     public String toString() {
13         return pair.toString();
14     }
15 }

In this file, we defined the SerializableClass that contains a Pair field. The SerializableClass implements theSerializable interface, but it refers to the Pair class which doesn’t.

NotSerializableExceptionExample_v2.java:

1 public class NotSerializableExceptionExample_v2 {
2     public static void main(String[] args) {
3         SerializableClass sClass = new SerializableClass("Key1"1);
4          
5         System.out.println("Trying to serialize the following object: " + sClass);
6         Serializer.serialize(sClass); // This statement throws a NotSerializableException
7     }
8 }

A sample execution is shown below:

01 Trying to serialize the following object: Pair:
02 java.io.NotSerializableException: main.java.Pair
03     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
04     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
05     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
06     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
07     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
08     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
09     at main.java.Serializer.serialize(Serializer.java:24)
10     at main.java.NotSerializableExceptionExample_v2.main(NotSerializableExceptionExample_v2.java:8)

How to deal with the NotSerializableException

  • The simplest solution is to find the class that throws the exception and make it implement the Serializable interface. However, this may not be feasible if the class that throws the exception belongs to a third-party library.
  • In case the class refers to non-serializable objects and these objects should not be serialized, then, you can declare these objects as transient. Once a field of a class is declared as transient, then, it is ignored by the serializable runtime. For example:
    TransientExample.java:

     

    01 import java.io.Serializable;
    02  
    03 public class TransientExample implements Serializable {
    04     private static final long serialVersionUID = 6128016096756071380L;
    05     private transient Pair pair = null;
    06      
    07     public TransientExample(String key, Integer value) {
    08         this.pair = new Pair(key, value);
    09     }
    10      
    11     @Override
    12     public String toString() {
    13         return pair.toString();
    14     }
    15 }

    In this file, we defined the TransientExample that contains a Pair field. The TransientExample implements theSerializable interface, but it refers to the Pair class which doesn’t. However, the reference is declared as transient and thus, the object can be serialized normally:

    NotSerializableExceptionExample_v3.java:

    1 public class NotSerializableExceptionExample_v3 {
    2     public static void main(String[] args) {
    3         TransientExample ex = new TransientExample("key"1);
    4          
    5         System.out.println("Trying to serialize the following object: " + ex);
    6         Serializer.serialize(ex);
    7         System.out.println("The " + ex + " object was successfully serialized!");
    8     }
    9 }

    A sample execution is shown below:

    1 Trying to serialize the following object: Pair:
    2 The Pair:  object was successfully serialized!

Download the Eclipse Project

The Eclipse project of this example: NotSerializableExceptionExample.zip.

 
This was a tutorial about the NotSerializableException in Java.

你可能感兴趣的:(Java)