2012-01-16 32 views
25

Có cách nào đáng tin cậy để chuyển đổi bất kỳ đối tượng nào thành Chuỗi và sau đó quay lại đối tượng tương tự không? Tôi đã thấy một số ví dụ về những người chuyển đổi chúng bằng cách sử dụng toString() và sau đó chuyển giá trị đó vào một hàm tạo để tái tạo lại đối tượng nhưng không phải tất cả các đối tượng đều có một hàm tạo như thế này để phương thức không hoạt động cho tất cả các trường hợp. Theo cách nào?Chuyển đổi một cách đáng tin cậy bất kỳ đối tượng nào thành Chuỗi và sau đó quay lại

Trả lời

51

Có, nó được gọi là serialization!

String serializedObject = ""; 

// serialize the object 
try { 
    ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
    ObjectOutputStream so = new ObjectOutputStream(bo); 
    so.writeObject(myObject); 
    so.flush(); 
    serializedObject = bo.toString(); 
} catch (Exception e) { 
    System.out.println(e); 
} 

// deserialize the object 
try { 
    byte b[] = serializedObject.getBytes(); 
    ByteArrayInputStream bi = new ByteArrayInputStream(b); 
    ObjectInputStream si = new ObjectInputStream(bi); 
    MyObject obj = (MyObject) si.readObject(); 
} catch (Exception e) { 
    System.out.println(e); 
} 
+5

Bạn quên đề cập đến base64, để có thể nhận trạng thái được tuần tự hóa thành một 'Chuỗi' và ngược lại =) – alf

+0

Bạn cần truy cập vào lớp để thực hiện việc này. Điều gì sẽ xảy ra nếu bạn đang nhập lớp từ một nơi nào đó mà bạn không có quyền truy cập vào? – user596186

+0

nếu lớp đó không phải là cuối cùng, nếu nó không đề cập đến một đối tượng không serializable và nếu bạn không có bất kỳ vấn đề thiết kế bạn có thể phân lớp nó và sau đó bạn có thể serialize phân lớp này. Tôi cũng không thử :) – HRgiger

5

Không ai hoạt động trong tất cả các trường hợp. Một đối tượng có thể, ví dụ: chứa tham chiếu đến các JVM khác đang xử lý trạng thái của chúng và trạng thái này có thể không có sẵn để bạn khôi phục.

Các sự cố khác mà bạn sắp gặp sẽ bao gồm các luồng mở, các ổ cắm nghe và hầu hết mọi thứ khác từ thế giới bên ngoài.

Không cần phải lặp lại rằng nhất ít nhất hai kỹ sư lõi Java nói rằng việc tuần tự hóa là một trong những sai lầm lớn nhất trong Java, tức là sau khi hoàn tất. (Tuy nhiên, tôi thích serialization, nhưng nó sẽ không tiện dụng. Nhưng nó sẽ không luôn luôn hoạt động.)

+0

@last Họ làm gì? Tôi có nghĩa là chúng ta cần một số loại cách để tồn tại các đối tượng và trong khi chắc chắn có những vấn đề với cách họ thực hiện serialization nó vẫn có vẻ là một điều cần thiết để có. Và nếu họ thực sự bắt đầu liệt kê các lỗi trong Java, tôi nghĩ việc serialization sẽ không xuất hiện ở top10 đối với tôi;) – Voo

+0

@Voo, cho đến nay tôi chỉ nghe Mark Reinhold và Josh Bloch nói rằng serialization là phần tồi tệ nhất trong Java, và nó bị bắt trên video: http://www.parleys.com/#st=5&id=2866 (hy vọng đây là bản trình bày mở và miễn phí) vào khoảng 35:14. Điều đó nói rằng, quyết định đến trong một giây, và nó đã được thừa nhận thậm chí còn tồi tệ hơn. – alf

12

Serialize thành mảng byte, chuyển thành Base64. Sau đó giải mã Base64 trở lại mảng byte và deserialize.

3

Có, đó là Nối tiếp Bạn có thể sử dụng, ObjectInputStream.readObject và ObjectOutputStream.writeObject. Xin vui lòng xem bên dưới Ví dụ:

MyClass myClass = new MyClass(); 
FileOutputStream fileStream = new FileOutputStream("myObjectFile.txt"); 
ObjectOutputStream os = new ObjectOutputStream(fileStream); 
os.writeObject(os); 
os.close(); 

FileInputStream fileInStream = new FileInputStream("myObjectFile.txt"); 
ObjectInputStream ois = new ObjectInputStream(fileInStream); 
MyClass myClass2 = ois.readObject(); 
ois.close(); 
+1

Tôi tin rằng bạn muốn viết os.writeObject (myClass); – cripox

7

Đây là mã:

đoạn
 try { 
        ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
        ObjectOutputStream so = new ObjectOutputStream(bo); 
        so.writeObject(stringList); 
        so.flush(); 
        redisString = new String(Base64.encode(bo.toByteArray()));   
      } 
      catch (Exception e) { 
        e.printStackTrace();  } 

     try { 
        byte b[] = Base64.decode(redisString.getBytes()); 
        ByteArrayInputStream bi = new ByteArrayInputStream(b); 
        ObjectInputStream si = new ObjectInputStream(bi); 
        List<String> stringList2 = (List<String>)si.readObject(); 
        System.out.println(stringList2.get(1));   
      } 
      catch (Exception e) { 
        e.printStackTrace();   
      } 
+0

Thêm sự phụ thuộc của Base64 –

+0

Người đàn ông tuyệt vời !! Bạn đã tiết kiệm rất nhiều thời gian cho tôi. –

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