Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why static transient field is serialized?

I´ve been reading that the static fields are not serialized but, after testing it, I saw that´s not true.

The static modifier even overrides the transient modifier and makes the field serializable.

I write one example from a book that shows that a static transient field is serialized.

import java.io.*;

class USPresident implements Serializable {

    private static final long serialVersionUID = 1L;

    @Override
    public String toString() {
        return "US President [name=" + name
                + ", period=" + period + ", term=" + term + "]";
    }

    public USPresident(String name, String period, String term) {
        this.name = name;
        this.period = period;
        this.term = term;
    }
    private String name;
    private String period;
    private  static transient  String term;
}

class TransientSerialization {

    public static void main(String[] args) {
        USPresident usPresident = new USPresident("Barack Obama", "2009 to --", "56th term");
        System.out.println(usPresident);
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("USPresident.data"))) {
            oos.writeObject(usPresident);
        } catch (IOException ioe) {
// ignore
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("USPresident.data"))) {
            Object obj = ois.readObject();
            if (obj != null && obj instanceof USPresident) {
                USPresident presidentOfUS = (USPresident) obj;
                System.out.println(presidentOfUS);

            }
        } catch (IOException ioe) {
// ignore
        } catch (ClassNotFoundException e) {
// ignore
        }
    }
}

Is wrong the general concept that static fields are not serialized? Is it just a recommendation? Why the transient modifier doen't take effect with static ?

note: I understand that initialize a static field in a constructor is an odd code, but the compiler let me do it and it's just in order to understand static fields serialization.

like image 632
bleras Avatar asked Jan 30 '26 07:01

bleras


1 Answers

This has nothing to do with serialization but due to the fact that you are setting the static field when you create your usPresident variable. This sets the field for the class of that JVM. Try reading in the serialized president in a different program and see that the transient field is not serialized.

As an aside: consider not ignoring your exceptions.


For example, refactored, your code could look like this:

class USPresident implements Serializable {

   private static final long serialVersionUID = 1L;

   @Override
   public String toString() {
      return "US President [name=" + name + ", period=" + period + ", term="
            + term + "]";
   }

   public USPresident(String name, String period, String term) {
      this.name = name;
      this.period = period;
      this.term = term;
   }

   private String name;
   private String period;
   private static transient String term;
}

class TransientSerialization {

   public static void main(String[] args) {
      serializePresident();
      deserializePresident();
   }

   private static void deserializePresident() {
      ObjectInputStream ois = null;
      try {
         ois = new ObjectInputStream(new FileInputStream(
               "USPresident.data"));
         Object obj = ois.readObject();
         if (obj != null && obj instanceof USPresident) {
            USPresident presidentOfUS = (USPresident) obj;
            System.out.println(presidentOfUS);

         }
      } catch (IOException ioe) {
         ioe.printStackTrace();
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      } finally {
         if (ois != null) {
            try {
               ois.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
   }

   private static void serializePresident() {
      USPresident usPresident = new USPresident("Barack Obama", "2009 to --",
            "56th term");
      System.out.println(usPresident);
      ObjectOutputStream oos = null;
      try {
         oos = new ObjectOutputStream(new FileOutputStream("USPresident.data"));
         oos.writeObject(usPresident);
         oos.close();
      } catch (IOException ioe) {
         ioe.printStackTrace();
      } finally {
         if (oos != null) {
            try {
               oos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
   }
}

The second time your run it, change the main method to:

   public static void main(String[] args) {
      // serializePresident();
      deserializePresident();
   }

And see what comes up.

For me, the first run returns:

US President [name=Barack Obama, period=2009 to --, term=56th term]
US President [name=Barack Obama, period=2009 to --, term=56th term]

and the second run returns:

US President [name=Barack Obama, period=2009 to --, term=null]
like image 136
Hovercraft Full Of Eels Avatar answered Feb 01 '26 21:02

Hovercraft Full Of Eels



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!