কিভাবে একটি ল্যাম্বডায় সিরিয়ালাইজ করবেন?


157

আমি কীভাবে মার্জিতভাবে একটি ল্যাম্বডাকে সিরিয়াল করতে পারি?

উদাহরণস্বরূপ, নীচের কোডটি একটি নিক্ষেপ করে NotSerializableExceptionSerializableRunnable"ডামি" ইন্টারফেস তৈরি না করে কীভাবে আমি এটি ঠিক করতে পারি ?

public static void main(String[] args) throws Exception {
    File file = Files.createTempFile("lambda", "ser").toFile();
    try (ObjectOutput oo = new ObjectOutputStream(new FileOutputStream(file))) {
        Runnable r = () -> System.out.println("Can I be serialized?");
        oo.writeObject(r);
    }

    try (ObjectInput oi = new ObjectInputStream(new FileInputStream(file))) {
        Runnable  r = (Runnable) oi.readObject();
        r.run();
    }
}

18
এটি সম্ভব হওয়ার সময় (নির্বাচিত উত্তর দেখুন), প্রত্যেকের পক্ষে সম্ভবত এটি করার বিষয়ে দুবার চিন্তা করা উচিত। এটি আনুষ্ঠানিকভাবে "দৃ disc়ভাবে নিরুৎসাহিত" এবং এটির গুরুতর নিরাপত্তাজনিত প্রভাব থাকতে পারে
ডেভিড

উত্তর:


260

জাভা 8 একাধিক সীমা যুক্ত করে প্রকারের ছেদ করতে কোনও বস্তু নিক্ষেপের সম্ভাবনার পরিচয় দেয় । সিরিয়ালাইজেশনের ক্ষেত্রে, সুতরাং এটি লেখা সম্ভব:

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

এবং ল্যাম্বদা স্বয়ংক্রিয়ভাবে সিরিয়ালযোগ্য হয়ে ওঠে।


4
খুব আকর্ষণীয় - এই বৈশিষ্ট্যটি বেশ শক্তিশালী বলে মনে হচ্ছে। Ingালাই লাম্বডাসের বাইরে কি এই জাতীয় castালাই প্রকাশের কোনও ব্যবহার আছে? উদাহরণস্বরূপ, এখন কোনও সাধারণ বেনাম শ্রেণীর সাথেও একই রকম কিছু করা সম্ভব?
বাল্ডার

6
@ বালদার ল্যাম্বডাসের প্রকারের অনুক্রমের জন্য একটি লক্ষ্য প্রকার সরবরাহ করার জন্য একটি চৌরাস্তা প্রকারে কাস্ট করার সুবিধা যুক্ত করা হয়েছিল। যেহেতু এআইসির একটি ম্যানিফেস্ট প্রকার থাকে (যেমন, এটির ধরণের অনুমান করা হয় না) একটি ছেদ করার ধরণের কাছে একটি এআইসি castালাই কার্যকর নয়। (এটি সম্ভব, কেবল দরকারী নয়)) একটি এআইসি একাধিক ইন্টারফেস প্রয়োগ করতে আপনাকে একটি নতুন সাব-ইন্টারফেস তৈরি করতে হবে যা সেগুলির সমস্তগুলি প্রসারিত করে, এবং তারপরে তা ইনস্ট্যান্ট করে তুলবে।
স্টুয়ার্ট

2
এটির কোনও সংকলক সতর্কতা উত্পন্ন করবে না, যা বলেছে যে কোনও সিরিয়াল ভার্সনইউইডি সংজ্ঞায়িত করা হয়নি?
কিরিল রাখমান

11
দ্রষ্টব্য: আপনি কেবল নির্মাণের সময় কাস্ট প্রয়োগ করলে এটি কেবল কাজ করে। নিম্নলিখিতটি একটি ক্লাসকাস্ট ধারণাটি ছুঁড়ে ফেলবে: চলমান r = () -> System.out.println ("সিরিয়ালাইজযোগ্য!"); চলমান সিরিয়ালাইজেবল আর = (চলমান ও সিরিয়ালাইজযোগ্য) আর;
বিসিডি

3
: @bcody হ্যাঁ তাও দেখতে stackoverflow.com/questions/25391656/...
assylias

24

একই নির্মাণ পদ্ধতি রেফারেন্সের জন্য ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ এই কোড:

import java.io.Serializable;

public class Test {
    static Object bar(String s) {
        return "make serializable";
    }

    void m () {
        SAM s1 = (SAM & Serializable) Test::bar;
        SAM s2 = (SAM & Serializable) t -> "make serializable";
    }

    interface SAM {
        Object action(String s);
    }
}

একটি ল্যাম্বডা এক্সপ্রেশন এবং একটি পদ্ধতি রেফারেন্সকে সিরিয়ালযোগ্য টার্গেট টাইপের সাথে সংজ্ঞায়িত করে।


18

খুব কুরুচিপূর্ণ castালাই। আমি যে ফাংশনাল ইন্টারফেসটি ব্যবহার করছি তাতে সিরিয়ালাইজেবল এক্সটেনশনটি সংজ্ঞায়িত করতে পছন্দ করি

উদাহরণ স্বরূপ:

interface SerializableFunction<T,R> extends Function<T,R>, Serializable {}
interface SerializableConsumer<T> extends Consumer<T>, Serializable {}

তারপরে ল্যাম্বদা গ্রহণের পদ্ধতিটি এরূপ হিসাবে সংজ্ঞায়িত করা যেতে পারে:

private void someFunction(SerializableFunction<String, Object> function) {
   ...
}

এবং ফাংশনটিতে কল করে আপনি কোনও লম্পট castালাই ছাড়াই আপনার ল্যাম্বদা পাস করতে পারবেন:

someFunction(arg -> doXYZ(arg));

2
আমি এই উত্তরটি পছন্দ করি কারণ তারপরে যে কোনও বাহ্যিক কলার আপনি লিখবেন না তা স্বয়ংক্রিয়ভাবে সিরিয়ালযোগ্যও হবে। আপনি যদি অবজেক্টগুলিকে সিরিয়ালাইজযোগ্য হিসাবে জমা দিতে চান তবে আপনার ইন্টারফেসটি সিরিয়ালাইজেবল হতে হবে যা একটি ইন্টারফেসের বিন্দুর মতো। যাইহোক, প্রশ্নটি "একটি SerializableRunnable'ডামি' ইন্টারফেস তৈরি না করে "
বলেছিল


3

আপনি যদি ক্রিয়োর মতো অন্য সিরিয়ালাইজেশন কাঠামোয় স্যুইচ করতে ইচ্ছুক হন তবে আপনি একাধিক সীমা বা বাস্তবায়িত ইন্টারফেস প্রয়োগ করতে হবে এমন প্রয়োজনীয়তা থেকে মুক্তি পেতে পারেন Serializable। পদ্ধতির হয়

  1. InnerClassLambdaMetafactoryসিরিয়ালাইজেশনের জন্য প্রয়োজনীয় কোডটি তৈরি করতে সর্বদা পরিবর্তন করুন ify
  2. LambdaMetaFactoryডিসিরিয়ালেসনের সময় সরাসরি কল করুন

বিশদ এবং কোডের জন্য এই ব্লগ পোস্টটি দেখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.