2011-12-25 36 views
28

Giả sử bạn có hai loại cổ phiếu này, Foo và Bar nơi Bar mở rộng Foo và thực hiện SerializableJava đối tượng serialization và thừa kế

class Foo { 

public String name; 

public Foo() { 
    this.name = "Default"; 
} 

public Foo(String name) { 
    this.name = name; 
} 
} 

class Bar extends Foo implements java.io.Serializable { 

public int id; 

public Bar(String name, int id) { 
    super(name); 
    this.id = id; 
} 
} 

ý rằng Foo không thực hiện Serializable. Vậy điều gì sẽ xảy ra khi thanh được tuần tự hóa?

public static void main(String[] args) throws Exception { 

    FileOutputStream fStream=new FileOutputStream("objects.dat"); 
    ObjectOutputStream oStream=new ObjectOutputStream(fStream); 
    Bar bar=new Bar("myName",21); 
    oStream.writeObject(bar); 

    FileInputStream ifstream = new FileInputStream("objects.dat"); 
    ObjectInputStream istream = new ObjectInputStream(ifstream); 
    Bar bar1 = (Bar) istream.readObject(); 
    System.out.println(bar1.name + " " + bar1.id); 

} 

nó in "Mặc định 21". Câu hỏi đặt ra là, tại sao hàm dựng mặc định được gọi khi lớp không được tuần tự hóa?

+1

Bạn không thể đột nhiên tạo ra các thể hiện của một lớp vô tội mà không cần gọi hàm tạo của nó, vì vậy đặc tả nối tiếp yêu cầu gọi một hàm tạo của các lớp không nối tiếp./Bạn có thể muốn có một proxy nối tiếp. –

Trả lời

20

Có thể tuần tự hóa chỉ là "giao diện điểm đánh dấu" cho một lớp nhất định.

Nhưng lớp đó phải tuân theo quy tắc nhất định:

http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

Để cho phép phân nhóm các lớp phi serializable để được tuần tự, các kiểu phụ có thể chịu trách nhiệm cho việc lưu và khôi phục lại tình trạng của các gói công khai, được bảo vệ và (nếu có) của siêu loại, các trường . Loại phụ có thể giả định trách nhiệm này chỉ khi lớp nó mở rộng có một hàm tạo không-arg có thể truy cập để khởi tạo trạng thái của lớp là . Đó là một lỗi để khai báo một lớp Serializable nếu điều này không phải là trường hợp.

để trả lời câu hỏi @Sleiman Jneidi hỏi trong bình luận, trong tài liệu oracle đề cập ở trên, nó đề cập rõ ràng

Trong deserialization, các lĩnh vực của các tầng lớp phi serializable sẽ được khởi tạo bằng cách sử dụng công cộng hoặc bảo vệ constructor no-arg của lớp. Một constructor no-arg phải được truy cập tới lớp con có thể tuần tự hóa được. Các trường lớp con có thể tuần tự hóa sẽ được khôi phục từ luồng.

Do đó, hàm tạo no-arg mặc định của lớp Foo được gọi là, dẫn đến khởi tạo.

+0

Tôi biết điều đó. nhưng tại sao nó gọi constructor mặc định. Tôi không hỏi Serializable là gì? –

+5

@sleimanjneidi vì "Để cho phép các kiểu con của các lớp không tuần tự hóa được tuần tự hóa, loại phụ có thể chịu trách nhiệm ** để lưu và khôi phục trạng thái của các trường gói công cộng, được bảo vệ và (nếu có) **. Điều này có nghĩa là 'Bar' sẽ đặt trường' tên_'' của 'Foo' bằng tay", vì 'Foo' không được nối tiếp – fge

4

có thể là the defaultWriteObject can only write the non-static and non-transient fields of the current class. Khi lớp cha không thực hiện giao diện Serializable, các trường trong siêu lớp không thể được tuần tự hóa vào luồng.

+0

Có nếu superclass không thực thi Serializable, nó sẽ không được tuần tự hóa, vì vậy khi deserialized, hàm khởi tạo mặc định của nó sẽ được gọi và các giá trị mặc định sẽ được phân bổ cho tất cả các biến của nó. – Akash5288

0

Thực ra khi bạn sẽ đọc đối tượng lớp cha trở lại vì nó không được sắp xếp theo thứ tự .. vì vậy không cần phải sắp xếp lại thứ gì nữa, JVM sẽ thực hiện quá trình tương tự như khi chúng ta tạo đối tượng mới bằng từ khóa mới.

Các vấn đề liên quan