java যবহ কিভাবে আপনি জাভা একটি বস্তুর একটি গভীর কপি করবেন?




জাভার ব্যবহার (14)

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

জাভাতে এটি একটি গভীর বস্তু কপি ফাংশন বাস্তবায়ন করা একটু কঠিন। মূল বস্তু এবং ক্লোনড এক ভাগের কোনও রেফারেন্স নিশ্চিত করার জন্য আপনি কী পদক্ষেপ গ্রহণ করেন?


ফাইল তৈরি না করে আপনি সিরিয়ালাইজেশনের সাথে একটি গভীর অনুলিপি তৈরি করতে পারেন।

আপনি গভীর অনুলিপি করতে চান আপনার বস্তু implement serializable করতে হবে। যদি শ্রেণীটি চূড়ান্ত না হয় বা সংশোধন করা যায় না, তবে শ্রেণি বাড়ান এবং সিরিয়ালাইজেশান প্রয়োগ করুন।

বাইট একটি প্রবাহে আপনার বর্গ রূপান্তর করুন:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(object);
oos.flush();
oos.close();
bos.close();
byte[] byteData = bos.toByteArray();

বাইট একটি প্রবাহ থেকে আপনার বর্গ পুনরুদ্ধার করুন:

ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
(Object) object = (Object) new ObjectInputStream(bais).readObject();

XStream যেমন ক্ষেত্রে সত্যিই দরকারী। এখানে cloning করতে একটি সহজ কোড

private static final XStream XSTREAM = new XStream();
...

Object newObject = XSTREAM.fromXML(XSTREAM.toXML(obj));

XStream ব্যবহার করুন ( http://x-stream.github.io/ )। আপনি এনটাইটেশনের মাধ্যমে কোনও বৈশিষ্ট্যগুলিকে উপেক্ষা করতে পারেন বা XStream ক্লাসে স্পষ্টভাবে সম্পত্তি নাম উল্লেখ করতে পারেন তা নিয়ন্ত্রণ করতে পারেন। তাছাড়া আপনি ক্লোনযোগ্য ইন্টারফেস বাস্তবায়ন করতে হবে না।


গভীর অনুলিপি বাস্তবায়ন করার এক উপায় হল প্রতিটি সংশ্লিষ্ট শ্রেণিতে কপি কন্সট্রকটার যোগ করা। একটি অনুলিপি কনস্ট্রাক্টর এটির একক যুক্তি হিসাবে 'এই' এর একটি উদাহরণ নেয় এবং এর থেকে সমস্ত মান কপি করে। বেশ কিছু কাজ, কিন্তু বেশ সহজবোধ্য এবং নিরাপদ।

সম্পাদনা করুন: নোট করুন যে ক্ষেত্রগুলি পড়তে অ্যাক্সেসার পদ্ধতিগুলি ব্যবহার করার প্রয়োজন নেই। আপনি সমস্ত ক্ষেত্র সরাসরি অ্যাক্সেস করতে পারেন কারণ উৎস ইনস্ট্যান্সটি সর্বদা অনুরূপ ধরনের অনুলিপি কনস্ট্রাক্টর সহ। স্পষ্ট কিন্তু উপেক্ষা করা হতে পারে।

উদাহরণ:

public class Order {

    private long number;

    public Order() {
    }

    /**
     * Copy constructor
     */
    public Order(Order source) {
        number = source.number;
    }
}


public class Customer {

    private String name;
    private List<Order> orders = new ArrayList<Order>();

    public Customer() {
    }

    /**
     * Copy constructor
     */
    public Customer(Customer source) {
        name = source.name;
        for (Order sourceOrder : source.orders) {
            orders.add(new Order(sourceOrder));
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

সম্পাদনা করুন: নোট করুন যে কপি কন্সট্রকটারগুলি ব্যবহার করার সময় আপনি যে অনুলিপিটি অনুলিপি করছেন তার রানটাইম টাইপটি আপনাকে জানতে হবে। উপরের পদ্ধতির সাথে আপনি সহজে একটি মিশ্র তালিকা অনুলিপি করতে পারবেন না (আপনি কিছু প্রতিফলন কোডের সাথে এটি করতে সক্ষম হবেন)।


Apache Commons একটি বস্তুর গভীর ক্লোন দ্রুত উপায়ে অফার করে।

My_Object object2= org.apache.commons.lang.SerializationUtils.clone(object1);

স্প্রিং ফ্রেমওয়ার্ক ব্যবহারকারীদের জন্য। ক্লাস ব্যবহার করে org.springframework.util.SerializationUtils ব্যবহার করে:

@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T object) {
     return (T) SerializationUtils.deserialize(SerializationUtils.serialize(object));
}

1)

public static Object deepClone(Object object) {
   try {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream(baos);
     oos.writeObject(object);
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
     ObjectInputStream ois = new ObjectInputStream(bais);
     return ois.readObject();
   }
   catch (Exception e) {
     e.printStackTrace();
     return null;
   }
 }

2)

    // (1) create a MyPerson object named Al
    MyAddress address = new MyAddress("Vishrantwadi ", "Pune", "India");
    MyPerson al = new MyPerson("Al", "Arun", address);

    // (2) make a deep clone of Al
    MyPerson neighbor = (MyPerson)deepClone(al);

এখানে আপনার MyPerson এবং MyAddress ক্লাসটি সিরিয়ালজেস ইন্টারফেস প্রয়োগ করতে হবে


import com.thoughtworks.xstream.XStream;

public class deepCopy {
    private static  XStream xstream = new XStream();

    //serialize with Xstream them deserialize ...
    public static Object deepCopy(Object obj){
        return xstream.fromXML(xstream.toXML(obj));
    }
}

জটিল বস্তুর জন্য এবং যখন কার্যক্ষমতা উল্লেখযোগ্য নয় তখন আমি gson লাইব্রেরী ব্যবহার করি, যেমন gson ক্রমবর্ধমান করতে, তারপর নতুন বস্তু পেতে পাঠ্যকে gson করে gson

প্রতিফলনের উপর ভিত্তি করে গসন বেশিরভাগ ক্ষেত্রেই কাজ করবে, ততক্ষণ transient ক্ষেত্রগুলি অনুলিপি করা হবে না এবং Error কারণে বৃত্তাকার রেফারেন্সের সাথে বস্তুগুলি তৈরি করা হবে না।

public static <T> T copy(T anObject, Class<T> classInfo) {
    Gson gson = new GsonBuilder().create();
    String text = gson.toJson(anObject);
    T newObject = gson.fromJson(text, classInfo);
    return newObject;
}
public static void main(String[] args) {
    String originalObject = "hello";
    String copiedObject = copy(originalObject, String.class);
}

আপনি এমন github.com/kostaskougios/cloning করতে github.com/kostaskougios/cloning যা একটি সহজ API রয়েছে এবং প্রতিফলন সহ অপেক্ষাকৃত দ্রুত ক্লোনিং সম্পাদন করে (সিরিয়ালাইজেশন পদ্ধতিগুলির চেয়ে দ্রুত হওয়া উচিত)।

Cloner cloner = new Cloner();

MyClass clone = cloner.deepClone(o);
// clone is a deep-clone of o

আপনি org.apache.commons.lang3.SerializationUtils.clone(T) ব্যবহার করে একটি সিরিয়ালাইজেশান-ভিত্তিক গভীর ক্লোন করতে পারেন org.apache.commons.lang3.SerializationUtils.clone(T) কমন্স ল্যাং-এ, কিন্তু সতর্ক org.apache.commons.lang3.SerializationUtils.clone(T)

সাধারণভাবে, ক্লোনিং প্রয়োজনে বস্তুর প্রতিটি গ্রাফের জন্য আপনার নিজস্ব ক্লোন পদ্ধতিগুলি লেখার সর্বোত্তম অনুশীলন।


কয়েকজন ব্যক্তি Object.clone() ব্যবহার করে বা overriding উল্লেখ করেছেন। এটা করবেন না। Object.clone() এর কিছু বড় সমস্যা রয়েছে এবং বেশিরভাগ ক্ষেত্রে এটির ব্যবহার নিরুৎসাহিত হয়। একটি সম্পূর্ণ উত্তর জন্য জোশুয়া Bloch দ্বারা " কার্যকর জাভা " থেকে আইটেম 11, অনুগ্রহ করে দেখুন। আমি বিশ্বাস করি আপনি আদিম টাইপ অ্যারেতে Object.clone() ব্যবহার করতে পারেন, তবে এটি ছাড়াও ক্লোনটি সঠিকভাবে ব্যবহার এবং ওভাররাইড করার বিষয়ে আপনাকে Object.clone() হতে হবে।

সিরিয়ালাইজেশন (এক্সএমএল বা অন্যথায়) উপর নির্ভর করে যে প্রকল্প kludgy হয়।

এখানে কোন সহজ উত্তর নেই। যদি আপনি কোন বস্তুর গভীর অনুলিপি করতে চান তবে আপনাকে বস্তুর গ্রাফটি অতিক্রম করতে হবে এবং প্রতিটি সন্তানের বস্তুর অনুলিপিটি অনুলিপি কন্সট্রাকটর বা স্ট্যাটিক ফ্যাক্টরি পদ্ধতির মাধ্যমে অনুলিপি করতে হবে যা ঘন ঘন শিশুর বস্তুকে অনুলিপি করে। Immutables (উদাহরণস্বরূপ String গুলি) কপি করা প্রয়োজন হবে না। একটি সরাইয়া হিসাবে, আপনি এই কারণে immutability পক্ষে উচিত।


জ্যাকসন JSON ব্যবহার করে জটিল জাভা অবজেক্টটি JSON এ সিরিয়ালাইজ করতে এবং এটি আবার পড়ার জন্য একটি খুব সহজ এবং সহজ পদ্ধতি।

http://wiki.fasterxml.com/JacksonInFiveMinutes





clone