ObjectStreamClass:监视Java对象的序列化
ObjectStreamClass可以是有用的類,用于分析JVM中加載的序列化類的序列化特征。 這篇文章介紹了此類提供的有關已加載序列化類的一些信息。
ObjectStreamClass提供了兩個用于查找類的靜態方法: lookup(class)和lookupAny(Class) 。 第一個lookup(Class)僅在提供的類可序列化時返回ObjectStreamClass的實例,如果提供的類不可序列化則返回null。 第二個方法lookupAny(Class)返回所提供類的ObjectStreamClass實例,而不管其是否可序列化。
一旦通過靜態“ lookup”方法提供了ObjectStreamClass實例,就可以查詢該實例的類名 , 序列號UID和可序列化的字段 。
為了演示ObjectStreamClass用法,我首先列出了兩個簡單類的代碼清單,它們將是演示的一部分。 一類Person是可序列化的 ,但具有一個過渡字段。 另一個類UnserializablePerson幾乎相同,但不可序列化。
人.java
package dustin.examples.serialization;import java.io.Serializable;/*** Person class intended for demonstration of ObjectStreamClass.* * @author Dustin*/ public class Person implements Serializable {private final String lastName;private final String firstName;transient private final String fullName;public Person(final String newLastName, final String newFirstName){this.lastName = newLastName;this.firstName = newFirstName;this.fullName = this.firstName + " " + this.lastName;}public String getFirstName(){return this.firstName;}public String getLastName(){return this.lastName;}public String getFullName(){return this.fullName;}@Overridepublic String toString(){return this.fullName;} }UnserializablePerson.java
package dustin.examples.serialization;/*** Person class intended for demonstration of ObjectStreamClass.* * @author Dustin*/ public class UnserializablePerson {private final String lastName;private final String firstName;private final String fullName;public UnserializablePerson(final String newLastName, final String newFirstName){this.lastName = newLastName;this.firstName = newFirstName;this.fullName = this.firstName + " " + this.lastName;}public String getFirstName(){return this.firstName;}public String getLastName(){return this.lastName;}public String getFullName(){return this.fullName;}@Overridepublic String toString(){return this.fullName;} }現在有了兩個可以與ObjectStreamClass結合使用的類,現在該看看一個簡單的演示應用程序,該應用程序演示ObjectStreamClass使用。
ObjectStreamClassDemo.java
package dustin.examples.serialization;import static java.lang.System.out;import java.io.ObjectStreamClass; import java.io.ObjectStreamField;/*** Demonstrates use of ObjectStreamDemo.* * @author Dustin*/ public class ObjectStreamClassDemo {/*** Displays class name, serial version UID, and serializable fields as* indicated by the provided instance of ObjectStreamClass.* * @param serializedClass */public static void displaySerializedClassInformation(final ObjectStreamClass serializedClass){final String serializedClassName = serializedClass.getName();out.println("Class Name: " + serializedClassName);final long serializedVersionUid = serializedClass.getSerialVersionUID();out.println("serialversionuid: " + serializedVersionUid);final ObjectStreamField[] fields = serializedClass.getFields();out.println("Serialized Fields:");for (final ObjectStreamField field : fields){out.println("\t" + field.getTypeString() + " " + field.getName());}}/*** Main function that demonstrates use of ObjectStreamDemo.* * @param arguments Command line arguments; none expected.*/public static void main(String[] arguments){// Example 1: ObjectStreamClass.lookup(Class) on a Serializable classout.println("\n=== ObjectStreamClass.lookup(Serializable) ===");final ObjectStreamClass serializedClass = ObjectStreamClass.lookup(Person.class);displaySerializedClassInformation(serializedClass);// Example 2: ObjectStreamClass.lookup(Class) on a class that is not// Serializable (which will result in a NullPointerException// when trying to access null returned from 'lookup'out.println("\n=== ObjectStreamClass.lookup(Unserializable) ===");try{final ObjectStreamClass unserializedClass =ObjectStreamClass.lookup(UnserializablePerson.class);displaySerializedClassInformation(unserializedClass);}catch (NullPointerException npe){out.println("NullPointerException: Unable to lookup unserializable class with ObjectStreamClass.lookup.");}// Example 3: ObjectStreamClass.lookupAny(Class) works without the// NullPointerException, but only provides name of the class as// Serial Version UID and serialized fields do not apply in the// case of a class that is not serializable.out.println("\n=== ObjectStreamClass.lookupAny(Unserializable) ===");final ObjectStreamClass unserializedClass =ObjectStreamClass.lookupAny(UnserializablePerson.class);displaySerializedClassInformation(unserializedClass);} }上面的源代碼中的注釋指示了正在演示的內容。 下一個屏幕快照中顯示了運行此類的輸出。
當上面顯示的輸出與之前的代碼相關聯時,我們可以進行一些與ObjectStreamClass相關的觀察。 這些包括以下事實:可序列化類的transient字段未作為可序列化字段之一返回。 我們還看到,如果提供給它的類不可序列化,則ObjectStreamClass.lookup(Class)方法將返回null。 ObjectStreamClass.lookupAny(Class)對于無法序列化的類返回ObjectStreamClass的實例,但是在這種情況下,只有該類的名稱可用。
上面的代碼顯示了1940442894442614965的Person.java的串行版本UID。當在命令行上運行 serialver時 ,將生成并顯示相同的串行版本UID。
以編程方式計算與Oracle JDK附帶的serialver工具所計算出的相同串行版本UID的功能的serialver在于,可以顯式地將相同的串行版本UID添加到生成的代碼中 ,而無論如何將其隱式添加。 任何需要了解類的隱式Serial Version UID的JVM友好腳本或工具(例如,用Groovy編寫的腳本)或工具,都可以使用ObjectStreamClass來獲取該Serial Version UID。
翻譯自: https://www.javacodegeeks.com/2014/02/objectstreamclass-peeking-at-a-java-objects-serialization.html
總結
以上是生活随笔為你收集整理的ObjectStreamClass:监视Java对象的序列化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 各国电脑键盘(世界各国键盘图)
- 下一篇: 中国ddos攻击事件(中国破案ddos攻