2017-05-05 32 views
6

Tôi muốn biết liệu tham chiếu đến một phương thức thể hiện của một đối tượng tùy ý của một kiểu cụ thể có thể tuần tự hóa hay không?Tham chiếu đến một phương thức thể hiện có thể tuần tự hóa trong Java 8?

Ví dụ:

public class MyClass { 
    public void foo() { 
     System.out.println("Serializable"); 
    } 
} 

SerializableConsumer

@FunctionalInterface 
public interface SerializableConsumer<T> extends Consumer<T>, Serializable { 
} 

và lĩnh vực là:

SerializableConsumer<MyClass> serializableMethod = MyClass::foo; 

EDITED

+1

Tại sao bạn hỏi về loại tham chiếu phương pháp cụ thể đó? Bạn có nghĩ rằng, nó đặc biệt so với các tham chiếu phương thức khác hoặc các biểu thức lambda? – Holger

+0

Tôi tin rằng câu hỏi của bạn là tài liệu tốt cho suy nghĩ, vì vậy tôi đã bình chọn nó. Tuy nhiên, tôi tò mò về trường hợp sử dụng của bạn ... Tại sao bạn cần serialize một tham chiếu phương pháp? –

+0

Đó là lĩnh vực đậu CDI với phạm vi hội thoại. Vì vậy, nó phải được serializable. – Saljack

Trả lời

5

Giả sử rằng SerializableFunction dùng để chỉ một loại mà kéo dài Serializable, tài liệu tham khảo phương pháp sẽ được serializable. Không có gì đặc biệt về kiểu tham chiếu phương thức cụ thể mà bạn đang yêu cầu.

Đáng chú ý nhất là “tham chiếu đến phương pháp thể hiện của đối tượng tùy ý” không chụp bất kỳ phiên bản nào của MyClass, do đó, thực tế là MyClass không phải là Serializable không quan trọng. Sẽ khác nếu bạn đang đề cập đến một phương pháp thể hiện của một cá thể cụ thể như object::foo, như trong trường hợp đó, đối tượng cũng phải được tuần tự hóa, sẽ không thành công khi chạy, nếu lớp của nó không thực hiện Serializable.

Điều gì sẽ không hoạt động, là tham chiếu phương thức void dưới dạng Function loại trả lại Void. Tôi không biết cách SerializableFunction<MyClass, Void> của bạn được xác định, nhưng nếu nó tương đương với Function<MyClass, Void>&Serializable, nó sẽ không hoạt động.

Khi bạn có một giao diện chức năng phù hợp, serializing tài liệu tham khảo phương pháp là không có vấn đề:

import java.io.*; 
import java.util.function.Consumer; 

public class MyClass { 
    public void foo() { 
     System.out.println("Serializable"); 
    } 
    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     Consumer<MyClass> consumer = (Consumer<MyClass>&Serializable)MyClass::foo; 

     byte[] serialized; 
     try(ByteArrayOutputStream baos=new ByteArrayOutputStream(); 
      ObjectOutputStream oos = new ObjectOutputStream(baos)) { 
      oos.writeObject(consumer); 
      oos.flush(); 
      serialized=baos.toByteArray(); 
     } 

     Consumer<MyClass> deserialized; 
     try(ByteArrayInputStream bais=new ByteArrayInputStream(serialized); 
      ObjectInputStream ois=new ObjectInputStream(bais)) { 
      deserialized = (Consumer<MyClass>)ois.readObject(); 
     } 

     deserialized.accept(new MyClass()); 
    } 
} 

Như đã nói, các tham chiếu tới một trường hợp cụ thể phải sắp đặt từng dụ mục tiêu, do đó, phụ thuộc vào serializability đó Ví dụ để

import java.io.*; 
import java.util.function.Consumer; 

public class MyClass { 
    public void foo() { 
     System.out.println("Serializable"); 
    } 
    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     Runnable runnable = (Runnable&Serializable)new MyClass()::foo; 

     byte[] serialized; 
     try(ByteArrayOutputStream baos=new ByteArrayOutputStream(); 
      ObjectOutputStream oos = new ObjectOutputStream(baos)) { 
      oos.writeObject(runnable); 
      oos.flush(); 
      serialized=baos.toByteArray(); 
     } 

     Runnable deserialized; 
     try(ByteArrayInputStream bais=new ByteArrayInputStream(serialized); 
      ObjectInputStream ois=new ObjectInputStream(bais)) { 
      deserialized = (Runnable)ois.readObject(); 
     } 

     deserialized.run(); 
    } 
} 

sẽ thất bại khi chạy với một java.io.NotSerializableException: MyClass, trừ khi bạn thay đổi MyClass để thực hiện Serializable.

+0

Cảm ơn câu trả lời của bạn.SerializableFunction là giao diện mở rộng Serializable. Kiểu trả về thực sự của tôi là Integer vì vậy đây là lỗi của tôi. – Saljack

0

Tôi biết bạn có thể tuần tự hóa một sự xuất hiện lambda (như bạn có thể thấy here)

Bây giờ, những gì bạn muốn làm chỉ là tự tuần tự hóa một biến? hoặc phương pháp? ... Tôi không biết tại sao, nhưng tôi không nghĩ rằng bạn có thể. Có lẽ bạn có thể đi con đường khác, như tạo ra một lambda và serialize nó, như trong bài viết ở trên:

Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!"); 
+3

biến tĩnh là * không * được tuần tự hóa. Có lẽ bạn nên đọc những gì bạn đã liên kết ... – Holger

+0

Hahaha haha ​​Tôi là một dunk, cảm ơn bạn rất nhiều ... Tôi nhớ hiểu biết ở tất cả! –

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