Java.util.Optal কেন সিরিয়ালাইজযোগ্য নয়, কীভাবে এই জাতীয় ক্ষেত্রগুলি দিয়ে বস্তুকে সিরিয়ালাইজ করা যায়


107

এনাম ক্লাসটি সিরিয়ালাইজযোগ্য তাই এনামগুলির সাথে বস্তুটিকে সিরিয়ালাইজ করতে কোনও সমস্যা নেই। অন্য কেসটি হল যেখানে শ্রেণিতে java.util.Optal ক্লাসের ক্ষেত্র রয়েছে। এক্ষেত্রে নিম্নলিখিত ব্যতিক্রম নিক্ষেপ করা হয়: java.io.NotSerializableException: java.util.Optal

এই জাতীয় ক্লাসগুলি কীভাবে ডিল করবেন, কীভাবে তাদের সিরিয়াল করবেন? রিমোট ইজেবিতে বা আরএমআইয়ের মাধ্যমে এই জাতীয় অবজেক্টগুলি পাঠানো কি সম্ভব?

এটি উদাহরণ:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Optional;

import org.junit.Test;

public class SerializationTest {

    static class My implements Serializable {

        private static final long serialVersionUID = 1L;
        Optional<Integer> value = Optional.empty();

        public void setValue(Integer i) {
            this.i = Optional.of(i);
        }

        public Optional<Integer> getValue() {
            return value;
        }
    }

    //java.io.NotSerializableException is thrown

    @Test
    public void serialize() {
        My my = new My();
        byte[] bytes = toBytes(my);
    }

    public static <T extends Serializable> byte[] toBytes(T reportInfo) {
        try (ByteArrayOutputStream bstream = new ByteArrayOutputStream()) {
            try (ObjectOutputStream ostream = new ObjectOutputStream(bstream)) {
                ostream.writeObject(reportInfo);
            }
            return bstream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

যদি Optionalচিহ্নিত করা হয় Serializable, তবে get()এমন কিছু যদি সিরিয়ালাইজযোগ্য না হয়ে ফিরে আসে তবে কী হবে ?
ডাব্লুডাব্লু

10
@WW। আপনি অবশ্যই পাবেন NotSerializableException,
লার্নের মারকুইস

7
@WW। এটি ঠিক সংগ্রহের মতো। সংগ্রহের ক্লাসগুলির বেশিরভাগ সিরিয়ালাইজযোগ্য, তবে সংগ্রহের উদাহরণগুলি কেবল তখনই সিরিয়ালাইজ করা যায় যদি সংগ্রহে থাকা প্রতিটি বস্তুটি ক্রমিকরূপেও সক্ষম হয়।
স্টুয়ার্ট

আমার ব্যক্তিগত গ্রহণযোগ্যতা: এটি সঠিকভাবে ইউনিট টেস্ট এমনকি বস্তুর সিরিয়ালকরণের জন্য মানুষকে মনে করিয়ে দেওয়ার মতো নয়। আমি নিজেই java.io.NotSerializableException (java.util.Optional) এর মধ্যে দৌড়েছি ;-(
ঘোস্টটিকেট

উত্তর:


171

এই উত্তরটি শিরোনামের প্রশ্নের উত্তরে "Shouldচ্ছিকটি সিরিয়ালাইজযোগ্য হওয়া উচিত নয়?" সংক্ষিপ্ত উত্তরটি হ'ল জাভা ল্যাম্বদা (জেএসআর -৩৩৫) বিশেষজ্ঞ গোষ্ঠী এটি বিবেচনা করেছে এবং প্রত্যাখ্যান করেছে । এই নোটটি এবং এটি এবং এটি একটি নির্দেশ করে যে Optionalকোনও ফিরতি মান অনুপস্থিত থাকতে পারে তখন প্রাথমিক নকশার লক্ষ্যটি ফাংশনগুলির রিটার্ন মান হিসাবে ব্যবহার করা উচিত। উদ্দেশ্যটি হ'ল কলকারী তাত্ক্ষণিকভাবে পরীক্ষা করে দেখুন Optionalএবং যদি উপস্থিত থাকে তবে প্রকৃত মানটি বের করে। মানটি অনুপস্থিত থাকলে, কলার একটি ডিফল্ট মান প্রতিস্থাপন করতে পারে, একটি ব্যতিক্রম ছুঁড়ে দিতে পারে বা অন্য কোনও নীতি প্রয়োগ করতে পারে। এটি সাধারণত সাবলীল পদ্ধতির শৃঙ্খলাবদ্ধ করে সম্পন্ন করা হয় যা স্ট্রিম পাইপলাইন (বা অন্যান্য পদ্ধতি) এর Optionalমান ফিরে দেয় calls

এটি কখনও কখনও Optionalঅন্যান্য উপায়ে ব্যবহারের উদ্দেশ্যে করা হয়নি যেমন optionচ্ছিক পদ্ধতি আর্গুমেন্টের জন্য বা কোনও বস্তুর ক্ষেত্র হিসাবে সংরক্ষণ করা । এবং এক্সটেনশনের মাধ্যমে Optionalসিরিয়ালাইজযোগ্য করে তুলতে এটি এটিকে অবিচ্ছিন্নভাবে সঞ্চয় করা বা কোনও নেটওয়ার্ক জুড়ে প্রেরণে সক্ষম করে, উভয়ই এর মূল নকশা লক্ষ্য থেকে অনেক বেশি ব্যবহারকে উত্সাহ দেয়।

সাধারণত Optionalক্ষেত্রের মধ্যে সঞ্চয় করার চেয়ে ডেটা সংগঠিত করার আরও ভাল উপায় রয়েছে । যদি কোনও প্রাপ্তি (যেমন getValueপ্রশ্নের পদ্ধতি হিসাবে ) Optionalক্ষেত্র থেকে আসলটি ফেরত দেয় তবে এটি প্রতিটি কলারকে খালি মূল্য নিয়ে কাজ করার জন্য কিছু নীতি প্রয়োগ করতে বাধ্য করে। এটি সম্ভবত কলকারীদের জুড়ে অসংলগ্ন আচরণের দিকে পরিচালিত করবে। যে ক্ষেত্রটি সেট করে সেই ক্ষেত্রটি সেট করার সময় কিছু নীতি প্রয়োগ করে তা প্রায়শই ভাল।

কখনও কখনও লোকেরা Optionalসংগ্রহ করতে পছন্দ করতে List<Optional<X>>বা পছন্দ করতে চায় Map<Key,Optional<Value>>। এটিও সাধারণত একটি খারাপ ধারণা। এটা তোলে এই ব্যবহারগুলির প্রতিস্থাপন করতে প্রায়ই ভালো Optionalসঙ্গে নাল-বস্তুর মান (প্রকৃত nullরেফারেন্স), অথবা কেবল বর্জন করতে সম্পূর্ণরূপে সংগ্রহ থেকে এই থেকে।


26
স্টুয়ার্ট ভাল হয়েছে। আমার অবশ্যই বলতে হবে এটি যুক্তিযুক্ত হলে এটি একটি অসাধারণ চেইন, এবং এটি এমন একটি অসাধারণ জিনিস যা কোনও শ্রেণীর নকশা তৈরি করতে পারে যা উদাহরণস্বরূপ সদস্যের ধরণ হিসাবে ব্যবহার করার উদ্দেশ্যে নয়। বিশেষত যখন জাভাদকে ক্লাস চুক্তিতে বলা হয় না। সম্ভবত তাদের ক্লাসের পরিবর্তে একটি টীকা নকশা করা উচিত ছিল।
মারকুইস অফ লর্ন

1
সুতার্টের উত্তরের পিছনে যৌক্তিকতার পক্ষে এটি একটি দুর্দান্ত ব্লগ পোস্ট: ব্লগ.জোদা.আর
ওয়েসলি হার্টফোর্ড

2
সিরিয়ালাইজযোগ্য ক্ষেত্রগুলি ব্যবহার করার দরকার নেই এমন ভাল জিনিস। এটি অন্যথায় বিপর্যয় হবে
কুড়ু

48
আকর্ষণীয় উত্তর, আমার কাছে যে নকশা পছন্দটি সম্পূর্ণ অগ্রহণযোগ্য এবং বিভ্রান্ত ছিল। আপনি বলছেন "সাধারণত কোনও ক্ষেত্রের মধ্যে একটি ptionচ্ছিক সংরক্ষণের চেয়ে ডেটা সংগঠিত করার আরও ভাল উপায় রয়েছে", অবশ্যই, সম্ভবত, কেন নয়, তবে এটি ভাষাটির নয় ডিজাইনের পছন্দ হওয়া উচিত। এটি জাভায় স্কাল বিকল্পগুলি গভীরভাবে মিস করায় এটি এর মধ্যে এটির একটি ((স্কালার বিকল্পগুলি সিরিয়ালাইজযোগ্য, এবং তারা মোনাদের নির্দেশিকা অনুসরণ করে)
গিলাইলে

36
"aচ্ছিকের জন্য প্রাথমিক নকশার লক্ষ্যটি ফাংশনের রিটার্ন মান হিসাবে ব্যবহার করা উচিত যখন কোনও রিটার্ন মান অনুপস্থিত থাকে" " ঠিক আছে, মনে হচ্ছে আপনি এগুলি কোনও দূরবর্তী ইজেবিতে ফেরতের মানগুলির জন্য ব্যবহার করতে পারবেন না। দুর্দান্ত ...
থিলো

15

Serializationআপনার পরিচালিত আসল রানটাইম বাস্তবায়ন থেকে অবিচ্ছিন্ন সিরিয়ালাইজড ফর্মটি ডিক্লোল করে অনেকগুলি সম্পর্কিত সমস্যার সমাধান করা যেতে পারে।

/** The class you work with in your runtime */
public class My implements Serializable {
    private static final long serialVersionUID = 1L;

    Optional<Integer> value = Optional.empty();

    public void setValue(Integer i) {
        this.value = Optional.ofNullable(i);
    }

    public Optional<Integer> getValue() {
        return value;
    }
    private Object writeReplace() throws ObjectStreamException
    {
        return new MySerialized(this);
    }
}
/** The persistent representation which exists in bytestreams only */
final class MySerialized implements Serializable {
    private final Integer value;

    MySerialized(My my) {
        value=my.getValue().orElse(null);
    }
    private Object readResolve() throws ObjectStreamException {
        My my=new My();
        my.setValue(value);
        return my;
    }
}

ক্লাসটি এমন আচরণOptional প্রয়োগ করে যা সম্ভবত অনুপস্থিত মানগুলির ব্যবহারের ক্ষেত্রে (ব্যবহারের তুলনায় null) ভাল কোড লেখার অনুমতি দেয় । তবে এটি আপনার ডেটার অবিচ্ছিন্ন উপস্থাপনে কোনও সুবিধা যুক্ত করে না। এটি কেবল আপনার সিরিয়ালযুক্ত ডেটা আরও বড় করে তুলবে ...

উপরের স্কেচটি জটিল দেখাতে পারে তবে এটি কেবলমাত্র একটি সম্পত্তি দিয়ে প্যাটার্নটি প্রদর্শন করে। আপনার শ্রেণিতে যত বেশি বৈশিষ্ট্য রয়েছে তার সরলতা আরও প্রকাশিত হওয়া উচিত।

এবং ভুলে যাবেন না, Myঅবিচ্ছিন্ন ফর্মটি খাপ খাইয়ে দেওয়ার কোনও প্রয়োজন ছাড়াই সম্পূর্ণরূপে বাস্তবায়ন পরিবর্তনের সম্ভাবনা …


2
+1, তবে আরও ক্ষেত্রের সাথে সেগুলি অনুলিপি করার জন্য আরও বয়লারপ্লেট থাকবে।
মার্কো টপলনিক

1
@ মারকো টপলনিক: সর্বাধিক, সম্পত্তি এবং দিকনির্দেশে একক লাইন। তবে class Myএটির জন্য উপযুক্ত কন্সট্রাক্টর সরবরাহ করে , যা আপনি সাধারণত এটি অন্যান্য ব্যবহারের পক্ষে সহজ হিসাবে কাজ করেন, এটি readResolveএকক-লাইন বাস্তবায়ন হতে পারে যাতে বয়লারপ্লেটটি সম্পত্তি হিসাবে একক লাইনে হ্রাস করতে পারে। যা প্রতিটি মিউটটেবল সম্পত্তি Myযাই হোক না কেন ক্লাসে কমপক্ষে সাত লাইন কোড আছে এই সত্যটি দেওয়া হয় না।
হোলার

আমি একই বিষয় জুড়ে একটি পোস্ট লিখেছি। এটি মূলত এই উত্তরের দীর্ঘ পাঠ্য সংস্করণ: সিরিয়ালাইজ Oচ্ছিক
নিকোলাই

ডাউনসাইড হ'ল: বিকল্পগুলির ব্যবহার করে এমন কোনও শিম / পোজোর জন্য আপনার এটি করা দরকার। তবে তবুও, দুর্দান্ত ধারণা।
ঘোস্টট্যাগ


4

এটি একটি কৌতূহল বাদ।

আপনাকে ক্ষেত্রটি চিহ্নিত করতে হবে transientএবং ফলাফলটি নিজেই writeObject()লিখেছিল এমন নিজস্ব কাস্টম পদ্ধতি get()এবং সেই readObject()পদ্ধতিটি Optionalস্ট্রিম থেকে পড়ার মাধ্যমে পুনরুদ্ধার করার একটি পদ্ধতি সরবরাহ করতে হবে । কল করার বিস্মরণ না defaultWriteObject()এবং defaultReadObject()যথাক্রমে।


যদি আমি কোনও শ্রেণীর কোডের মালিক হয়ে থাকি তবে এটি কোনও ক্ষেত্রে কেবল অবজেক্টটি সঞ্চয় করা আরও বেশি সুবিধাজনক। এ জাতীয় ক্ষেত্রে ptionচ্ছিক ক্লাসটি ক্লাসের ইন্টারফেসের জন্য সীমাবদ্ধ থাকবে (পদ্ধতিটি ptionচ্ছিক ফিরে আসবে Nফমনাল (ক্ষেত্র))। তবে অভ্যন্তরীণ প্রতিনিধিত্বের জন্য valueচ্ছিক ব্যবহার করা সম্ভব নয় স্পষ্টভাবে অভিপ্রায় করতে মানটি alচ্ছিক।
ভানারচি

আমি শুধু দেখিয়েছেন এটি হয় সম্ভব। যদি আপনি কোনও কারণে অন্যথায় ভাবেন, তবে আপনার প্রশ্নটি আসলে কী?
মারকুইস

আপনার উত্তরের জন্য আপনাকে ধন্যবাদ, এটি আমার জন্য একটি বিকল্প যুক্ত করে। আমার মন্তব্যে আমি এই বিষয়টিতে আরও চিন্তাভাবনা দেখাতে চেয়েছি, প্রো এবং প্রতিটি সমাধানের বিপরীতে বিবেচনা করতে চাই। ব্যবহারের ক্ষেত্রে রাইটওজেক্ট / রিডঅবজেক্ট পদ্ধতিতে আমাদের রাষ্ট্রীয় উপস্থাপনে inচ্ছিকের সুস্পষ্ট অভিপ্রায় রয়েছে, তবে সিরিয়ালাইজেশন বাস্তবায়ন আরও জটিল হয়ে ওঠে। যদি ক্ষেত্রটি গণনা / স্ট্রিমগুলিতে নিবিড়ভাবে ব্যবহৃত হয় - তবে রাইটওজেক্ট / রিডঅবজেক্টটি ব্যবহার করা আরও সুবিধাজনক।
ভানার্চি

মন্তব্যগুলি নীচে প্রদর্শিত উত্তরগুলির সাথে প্রাসঙ্গিক হওয়া উচিত। আপনার সংগীতগুলির প্রাসঙ্গিকতা আমার কাছে স্পষ্টভাবে অব্যাহতি দেয়।
লার্নের মারকুইস

3

ভ্যাবরিও লাইব্রেরিতে (প্রাক্তন জাভাসলং) ক্লাসও রয়েছে Optionযা সিরিয়ালযোগ্য:

public interface Option<T> extends Value<T>, Serializable { ... }

0

আপনি যদি আরও সুসংগত ধরণের তালিকা বজায় রাখতে চান এবং নাল ব্যবহার করা এড়াতে চান তবে একটি বিকল্প উপায় আছে।

আপনি বিভিন্ন ধরণের ছেদ ব্যবহার করে মানটি সঞ্চয় করতে পারেন । ল্যাম্বদার সাথে মিলিত, এটি এর মতো কিছুতে অনুমতি দেয়:

private final Supplier<Optional<Integer>> suppValue;
....
List<Integer> temp = value
        .map(v -> v.map(Arrays::asList).orElseGet(ArrayList::new))
        .orElse(null);
this.suppValue = (Supplier<Optional<Integer>> & Serializable)() -> temp==null ? Optional.empty() : temp.stream().findFirst();

রয়ে tempমালিক উপর বন্ধ পরিবর্তনশীল পৃথক এড়াতে valueসদস্য এবং এইভাবে অত্যধিক serialising।

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