|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
java.lang.Object java.io.InputStream java.io.ObjectInputStream
public class ObjectInputStream
ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本資料和物件進行反序列化。
ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時,可以為應用程序提供對物件圖形的持久存儲。ObjectInputStream 用於恢復那些以前序列化的物件。其他用途包括使用Socket串流在主機之間傳遞物件,或者用於編組和解組遠端通信系統中的實參和形參。
ObjectInputStream 確保從串流創建的圖形中所有物件的型別與 Java 虛擬機器中顯示的類別相比對。使用標準機制按需載入類別。
只有支持 java.io.Serializable 或 java.io.Externalizable 介面的物件才能從串流讀取。
readObject
方法用於從串流讀取物件。應該使用 Java 的安全強制轉換來獲取所需的型別。在 Java 中,字元串和陣列都是物件,所以在序列化期間將其視為物件。讀取時,需要將其強制轉換為期望的型別。
可以使用 DataInput 上的適當方法從串流讀取基本資料型別。
預設情況下,物件的反序列化機制會將每個欄位的內容恢復為寫入時它所具有的值和型別。反序列化進程將忽略宣告為瞬態或靜態的欄位。對其他物件的參考使得根據需要從串流中讀取這些物件。使用參考共享機制能夠正確地恢復物件的圖形。反序列化時始終分派新物件,這樣可以避免現有對象被覆寫。
讀取物件類似於運行新物件的建構子。為物件分派記憶體並將其初始化為零 (NULL)。為不可序列化類別調用無參數建構子,然後從以最接近 java.lang.object 的可序列化類別開始和以物件的最特定類別結束的串流恢復可序列化類別的欄位。
例如,要從由 ObjectOutputStream 中的範例寫入的串流讀取:
FileInputStream fis = new FileInputStream("t.tmp"); ObjectInputStream ois = new ObjectInputStream(fis); int i = ois.readInt(); String today = (String) ois.readObject(); Date date = (Date) ois.readObject(); ois.close();
類別控制實作 java.io.Serializable 或 java.io.Externalizable 介面時的序列化方式。
實作 Serializable 介面允許物件序列化,以保存和恢復物件的全部狀態,並且允許類別在寫入串流時的狀態和從串流讀取時的狀態之間變化。它自動遍歷物件之間的參考,保存和恢復全部圖形。
在序列化和反序列化進程中需要特殊處理的 Serializable 類別應該實作以下方法:
private void writeObject(java.io.ObjectOutputStream stream) throws IOException; private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException;
readObject 方法負責使用通過對應的 writeObject 方法寫入串流的資料,為特定類別讀取和恢復物件的狀態。該方法本身的狀態,不管是屬於其父級類別還是屬於其子類別,都沒有關係。恢復狀態的方法是,從個別欄位的 ObjectInputStream 讀取資料並將其分派給物件的適當欄位。DataInput 支持讀取基本資料型別。
嘗試讀取由對應的 writeObject 方法寫入的超出自定義資料邊界的物件資料將導致拋出 OptionalDataException(eof 欄位值為 true)。超出已分派資料末尾的非物件讀取以指示串流末尾的方式反映資料結束:按位讀取與位元組讀取或位元組數讀取一樣,將返回 -1,基元讀取將拋出 EOFException。如果不存在對應的 writeObject 方法,則預設的序列化資料的末尾標記已分派資料的末尾。
從 readExternal 方法發出的基元和物件讀取調用的行為方式一樣:如果串流已經定位在由相應 writeExternal 方法寫入的資料末尾,則物件讀取將拋出 OptionalDataException(其 eof 設置為 true),按位讀取將返回 -1,基元讀取將拋出 EOFException。注意,此行為不適用於使用舊 ObjectStreamConstants.PROTOCOL_VERSION_1
協議寫入的串流,在這些串流中,沒有劃分出由 writeExternal 方法寫入的資料末尾,因此無法檢測。
如果序列化串流沒有將給定類別列為要反序列化的物件的父級類別,則 readObjectNoData 方法負責初始化其特定類別的物件狀態。在接收方使用的反序列化實例類別的版本不同於發送方,並且接收者版本擴展的類別不是發送者版本擴展的類別時,此事可能發生。如果序列化串流已經被篡改,也會發生這種情況;因此,不管源串流是“敵意的”還是不完整的,readObjectNoData 方法都可以用來正確地初始化反序列化的物件。
對於沒有實作 java.io.Serializable 介面的任何物件,序列化不會對其欄位進行讀取或賦值。非 serializable 的 Object 的子類別可以為 serializable。在此情況下,非 serializable 類別必須具有無參數的建構子以允許其欄位能被初始化。在此情況下,子類別負責保存和恢復非 serializable 類別的狀態。經常出現的情況是,該類別的欄位是可存取的(public、package 或 protected),或者存在可用於恢復狀態的 get 和 set 方法。
反序列化物件進程中發生的所有異常將由 ObjectInputStream 捕獲並將中止讀取進程。
實作 Externalizable 介面允許物件假定可以完全控制物件的序列化形式的內容和格式。調用 Externalizable 介面的方法(writeExternal 和 readExternal)來保存和恢復物件狀態。當這兩種方法被某個類別實作時,它們可以使用 ObjectOutput 和 ObjectInput 的所有方法讀寫其本身的狀態。物件負責處理出現的任何版本控制。
Enum 常數的反序列化不同於普通的 serializable 或 externalizable 物件。Enum 常數的序列化形式只包含其名稱;不傳送常數的欄位值。要反序列化 enum 常數,ObjectInputStream 需要從串流中讀取常數的名稱;然後將 enum 常數的基本型別和接收到的常數名稱作為參數,調用靜態方法 Enum.valueOf(Class, String)
獲取反序列化的常數。與其他 serializable 或 externalizable 物件一樣,enum 常數可以作為序列化串流中隨後出現的反向參考的目標。不可以自定義 enum 常數的反序列化進程:在反序列化期間,enum 型別所定義的任何與類別有關的 readObject、readObjectNoData 和 readResolve 方法都將被忽略。類似地,任何 serialPersistentFields 或 serialVersionUID 欄位宣告也將被忽略(所有 enum 型別都有一個固定的 0L 的 serialVersionUID)。
DataInput
,
ObjectOutputStream
,
Serializable
,
物件序列化規範:Object Input Classes 第三節巢狀類別摘要 | |
---|---|
static class |
ObjectInputStream.GetField
提供對從輸入串流讀取的持久欄位的存取權限。 |
欄位摘要 |
---|
建構子摘要 | |
---|---|
protected |
ObjectInputStream()
為完全重新實作 ObjectInputStream 的子類別提供一種方式,讓它不必分派僅由 ObjectInputStream 的實作使用的私有資料。 |
|
ObjectInputStream(InputStream in)
創建從指定 InputStream 讀取的 ObjectInputStream。 |
方法摘要 | |
---|---|
int |
available()
返回可以不受阻塞地讀取的位元組數。 |
void |
close()
關閉輸入串流。 |
void |
defaultReadObject()
從此串流讀取當前類別的非靜態和非瞬態欄位。 |
protected boolean |
enableResolveObject(boolean enable)
使串流允許從該串流讀取的物件被替代。 |
int |
read()
讀取資料位元組。 |
int |
read(byte[] buf,
int off,
int len)
讀入 byte 陣列。 |
boolean |
readBoolean()
讀取一個 boolean 值。 |
byte |
readByte()
讀取一個 8 位的位元組。 |
char |
readChar()
讀取一個 16 位的 char 值。 |
protected ObjectStreamClass |
readClassDescriptor()
從序列化串流讀取類別描述符。 |
double |
readDouble()
讀取一個 64 位的 double 值。 |
ObjectInputStream.GetField |
readFields()
按名稱從串流中讀取持久欄位並使其可用。 |
float |
readFloat()
讀取一個 32 位的 float 值。 |
void |
readFully(byte[] buf)
讀取位元組,同時阻塞直至讀取所有位元組。 |
void |
readFully(byte[] buf,
int off,
int len)
讀取位元組,同時阻塞直至讀取所有位元組。 |
int |
readInt()
讀取一個 32 位的 int 值。 |
String |
readLine()
已過時。 此方法不能正確地將位元組轉換為字元。請參見 DataInputStream 以獲取詳細資訊和替代方法。 |
long |
readLong()
讀取一個 64 位的 long 值。 |
Object |
readObject()
從 ObjectInputStream 讀取物件。 |
protected Object |
readObjectOverride()
此方法由 ObjectOutputStream 的受信任子類別調用,這些子類別使用受保護的無參數建構子建構 ObjectOutputStream。 |
short |
readShort()
讀取一個 16 位的 short 值。 |
protected void |
readStreamHeader()
提供的 readStreamHeader 方法允許子類別讀取並驗證它們自己的串流頭部。 |
Object |
readUnshared()
從 ObjectInputStream 讀取“非共享”物件。 |
int |
readUnsignedByte()
讀取一個無符號的 8 位位元組。 |
int |
readUnsignedShort()
讀取一個無符號的 16 位 short 值。 |
String |
readUTF()
讀取 UTF-8 修改版格式的 String。 |
void |
registerValidation(ObjectInputValidation obj,
int prio)
在返回圖形前註冊要驗證的物件。 |
protected Class<?> |
resolveClass(ObjectStreamClass desc)
載入指定串流類別描述的本地等價類別。 |
protected Object |
resolveObject(Object obj)
在反序列化期間,此方法允許 ObjectInputStream 的受信任子類別使用一個物件替代另一個。 |
protected Class<?> |
resolveProxyClass(String[] interfaces)
返回一個代理類別,該類別實作在代理類別描述符中命名的介面;子類別可以實作此方法,以便從串流及動態代理類別的描述符中讀取自定義資料,允許它們使用介面和代理類別的替換載入機制。 |
int |
skipBytes(int len)
跳過位元組。 |
從類別 java.io.InputStream 繼承的方法 |
---|
mark, markSupported, read, reset, skip |
從類別 java.lang.Object 繼承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
從介面 java.io.ObjectInput 繼承的方法 |
---|
read, skip |
建構子詳細資訊 |
---|
public ObjectInputStream(InputStream in) throws IOException
如果安裝了安全管理器,則覆寫 ObjectInputStream.readFields 或 ObjectInputStream.readUnshared 方法的子類別的建構子直接或間接調用此建構子時,它將對 "enableSubclassImplementation" SerializablePermission 進行檢查。
in
- 要從中讀取的輸入串流
StreamCorruptedException
- 如果串流的頭部不正確
IOException
- 如果讀取串流頭部時發生 I/O 錯誤
SecurityException
- 如果不受信任的子類別非法覆寫安全敏感的方法
NullPointerException
- 如果 in
為 null
ObjectInputStream()
,
readFields()
,
ObjectOutputStream.ObjectOutputStream(OutputStream)
protected ObjectInputStream() throws IOException, SecurityException
如果已經安裝了安全管理器,則此方法首先通過 SerializablePermission("enableSubclassImplementation")
權限調用安全管理器的 checkPermission
方法,以確保可以啟用子類別化。
SecurityException
- 如果安全管理器存在並且其 checkPermission
方法不允許啟用子類別化。
IOException
SecurityManager.checkPermission(java.security.Permission)
,
SerializablePermission
方法詳細資訊 |
---|
public final Object readObject() throws IOException, ClassNotFoundException
通過完全恢復根物件的所有欄位及其參考的物件來完全恢復根物件。此時,物件驗證回調的執行順序基於其註冊優先級。回調由物件在其個別恢復時(通過 readObject 特定方法)進行註冊。
當 InputStream 中出現問題或者遇到不應反序列化的類別時,將拋出異常。所有異常對於 InputStream 而言都是致命的,將使其處於不確定狀態;是忽略還是恢復串流狀態取決於調用者。
ObjectInput
中的 readObject
ClassNotFoundException
- 找不到序列化物件的類別。
InvalidClassException
- 序列化使用的類別出了問題。
StreamCorruptedException
- 串流中的控制資訊不一致。
OptionalDataException
- 在串流中找到基本型別資料而非物件。
IOException
- 任何常規的輸入/輸出相關的異常。protected Object readObjectOverride() throws IOException, ClassNotFoundException
ClassNotFoundException
- 找不到序列化物件的類別定義。
OptionalDataException
- 在串流中找到基本型別資料而非物件。
IOException
- 如果從底層串流執行讀操作時發生 I/O 錯誤ObjectInputStream()
,
readObject()
public Object readUnshared() throws IOException, ClassNotFoundException
覆寫此方法的 ObjectInputStream 子類別只能在處理 "enableSubclassImplementation" SerializablePermission 的安全上下文中建構;在不具有此權限的情況下,任何實例化這種子類別的嘗試都將導致拋出 SecurityException。
ClassNotFoundException
- 如果找不到要反序列化的物件的類別
StreamCorruptedException
- 如果串流中的控制資訊不一致
ObjectStreamException
- 如果串流中已經出現了要反序列化的物件
OptionalDataException
- 如果基本資料是串流中的下一項
IOException
- 如果在反序列化期間發生 I/O 錯誤public void defaultReadObject() throws IOException, ClassNotFoundException
ClassNotFoundException
- 如果找不到序列化物件的類別。
IOException
- 如果發生 I/O 錯誤。
NotActiveException
- 如果目前串流沒有正在讀取物件。public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException
GetField
物件
ClassNotFoundException
- 如果找不到序列化物件的類別。
IOException
- 如果發生 I/O 錯誤。
NotActiveException
- 如果目前串流沒有正在讀取物件。public void registerValidation(ObjectInputValidation obj, int prio) throws NotActiveException, InvalidObjectException
obj
- 接收驗證回調的物件。prio
- 控制回調的順序;零是個好的預設值。使用較大數進行較早的回調,使用較小數進行較晚的回調。在一個優先級中,回調的處理沒有特定順序。
NotActiveException
- 因為目前串流沒有正在讀取物件,所以註冊回調無效。
InvalidObjectException
- 驗證物件為 null。protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
ObjectOutputStream
中的相應方法是 annotateClass
。對於串流中的每個唯一類別,此方法只調用一次。此方法可以由子類別實作,從而使用替換載入機制,但是必須返回 Class
物件。返回後,如果該類別不是陣列類別,則它的 serialVersionUID 將與序列化類別的 serialVersionUID 進行比較,如果不比對,則反序列化失敗,並拋出 InvalidClassException
。
在 ObjectInputStream
中此方法的預設實作返回調用
Class.forName(desc.getName(), false, loader)的結果,其中
loader
按以下情形確定:如果當前執行緒的堆疊(stack)空間上存在一種方法,它的宣告類別由使用者定義的類別載入器定義(不是一個為實作反射調用而產生的類別),則 loader
是對應於最接近當前執行幀的這些方法的類別載入器;否則,loader
為 null
。如果此調用導致拋出 ClassNotFoundException
,且傳遞的 ObjectStreamClass
實例的名稱是 Java 語言中基本資料型別或 void 關鍵字,那麼將返回表示該基本型別或 void 的 Class
物件(例如,名稱為 "int"
的 ObjectStreamClass
將被解析為 Integer.TYPE
)。否則,將向此方法的調用者拋出 ClassNotFoundException
。
desc
- ObjectStreamClass
類別的實例
desc
的 Class
物件
IOException
- 任何常規輸入/輸出異常
ClassNotFoundException
- 如果找不到序列化物件的類別。protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException
對於串流中的每個唯一的代理類別描述符,此方法只調用一次。
ObjectOutputStream
中的相應方法是 annotateProxyClass
。對於覆寫此方法的 ObjectInputStream
的給定子類別,ObjectOutputStream
的相應子類別中的 annotateProxyClass
方法必須寫入由此方法讀取的任何資料或物件。
ObjectInputStream
中此方法的預設實作返回調用 Proxy.getProxyClass
的結果,同時帶有在 interfaces
參數中指定介面的 Class
物件的列表。每個介面名稱 i
的 Class
物件都是調用以下語句返回的值
Class.forName(i, false, loader)其中,
loader
是執行堆疊(stack)空間上的第一個非 null
類別載入器,如果在堆疊(stack)空間上不存在非 null
載入器(類別載入器選項與 resolveClass
方法使用的相同),則為 null
。如果所有解析的介面都是公共的,則 loader
的這一相同值還是傳遞給 Proxy.getProxyClass
的類別載入器;如果出現非公共介面,則傳遞他們的類別載入器(如果遇到一個以上的非公共介面類別載入器,則拋出 IllegalAccessError
)。如果 Proxy.getProxyClass
拋出 IllegalArgumentException
,則 resolveProxyClass
將拋出包含 IllegalArgumentException
的 ClassNotFoundException
。
interfaces
- 代理類別描述符中反序列化的介面名稱的列表
IOException
- 底層 InputStream
拋出任何異常
ClassNotFoundException
- 如果找不到代理類別或任何指定介面ObjectOutputStream.annotateProxyClass(Class)
protected Object resolveObject(Object obj) throws IOException
此方法在讀取物件之後而在從 readObject 返回之前調用。預設的 resolveObject 方法僅返回相同的物件。
子類別在取代物件時,必須確保替代對象與存儲參考的每個欄位相容。如果物件的型別不是欄位或陣列元素型別的子類別,則通過引發異常中止序列化並且不存儲物件。
此方法僅在首次遇到每個物件時調用一次。物件的所有後續參考都將被重定向到新物件。
obj
- 要替代的物件
IOException
- 任何常規的輸入/輸出異常。protected boolean enableResolveObject(boolean enable) throws SecurityException
如果 enable 為真,並且安裝了安全管理器,則此方法首先使用 SerializablePermission("enableSubstitution")
權限調用安全管理器的 checkPermission
方法,以確保使串流允許從該串流讀取的物件被替代。
enable
- 如果為 true,則允許為每個要反序列化的物件使用 resolveObject
SecurityException
- 如果安全管理器存在,且其 checkPermission
方法拒絕串流允許從要替代的串流讀取物件。SecurityManager.checkPermission(java.security.Permission)
,
SerializablePermission
protected void readStreamHeader() throws IOException, StreamCorruptedException
IOException
- 如果從底層 InputStream
讀取時發生 I/O 錯誤
StreamCorruptedException
- 如果串流中的控制資訊不一致protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException
writeClassDescriptor
方法編寫的)。預設情況下,此方法根據物件序列化規範中定義的格式讀取類別描述符。
IOException
- 如果發生 I/O 錯誤。
ClassNotFoundException
- 如果找不到類別描述符表示形式中使用的序列化物件的 ClassObjectOutputStream.writeClassDescriptor(java.io.ObjectStreamClass)
public int read() throws IOException
ObjectInput
中的 read
InputStream
中的 read
IOException
- 如果發生 I/O 錯誤。public int read(byte[] buf, int off, int len) throws IOException
ObjectInput
中的 read
InputStream
中的 read
buf
- 讀入資料的緩衝區off
- 資料的初始偏移量len
- 讀取的最大位元組數
IOException
- 如果發生 I/O 錯誤。DataInputStream.readFully(byte[],int,int)
public int available() throws IOException
ObjectInput
中的 available
InputStream
中的 available
IOException
- 如果從底層 InputStream
讀取時發生 I/O 錯誤public void close() throws IOException
Closeable
中的 close
ObjectInput
中的 close
InputStream
中的 close
IOException
- 如果發生 I/O 錯誤。public boolean readBoolean() throws IOException
DataInput
中的 readBoolean
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public byte readByte() throws IOException
DataInput
中的 readByte
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public int readUnsignedByte() throws IOException
DataInput
中的 readUnsignedByte
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public char readChar() throws IOException
DataInput
中的 readChar
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public short readShort() throws IOException
DataInput
中的 readShort
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public int readUnsignedShort() throws IOException
DataInput
中的 readUnsignedShort
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public int readInt() throws IOException
DataInput
中的 readInt
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public long readLong() throws IOException
DataInput
中的 readLong
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public float readFloat() throws IOException
DataInput
中的 readFloat
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public double readDouble() throws IOException
DataInput
中的 readDouble
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public void readFully(byte[] buf) throws IOException
DataInput
中的 readFully
buf
- 讀入資料的緩衝區
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public void readFully(byte[] buf, int off, int len) throws IOException
DataInput
中的 readFully
buf
- 讀入資料的緩衝區off
- 資料的初始偏移量len
- 要讀取的最大位元組數
EOFException
- 如果到達檔案末尾。
IOException
- 如果發生其他 I/O 錯誤。public int skipBytes(int len) throws IOException
DataInput
中的 skipBytes
len
- 要跳過的位元組數
IOException
- 如果發生 I/O 錯誤。@Deprecated public String readLine() throws IOException
DataInput
中的 readLine
IOException
- 如果從底層 InputStream
讀取時發生 I/O 錯誤public String readUTF() throws IOException
DataInput
中的 readUTF
IOException
- 如果從底層 InputStream
讀取時發生 I/O 錯誤
UTFDataFormatException
- 如果讀取的位元組不表示有效的 UTF-8 修改版編碼的字元串
|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only。