জাভা ক্লোনযোগ্য সম্পর্কে


96

আমি জাভা সম্পর্কে ব্যাখ্যা করে কিছু টিউটোরিয়াল খুঁজছিলাম Cloneable, কিন্তু কোনও ভাল লিঙ্ক পাই নি, এবং স্ট্যাক ওভারফ্লো যেভাবেই আরও সুস্পষ্ট পছন্দ হয়ে উঠছে।

আমি নিম্নলিখিত জানতে চাই:

  1. Cloneableমানে আমাদের Cloneableইন্টারফেস প্রয়োগ করে ক্লোন বা অবজেক্টের একটি অনুলিপি থাকতে পারে । এটি করার সুবিধা এবং অসুবিধাগুলি কী কী?
  2. যদি বস্তুটি একটি যৌগিক বস্তু হয় তবে পুনরাবৃত্ত ক্লোনিং কীভাবে ঘটবে?

4
এর তুলনায় সুবিধা-অসুবিধাগুলি কী?
গ্যালাকটাস

4
আমি ক্লাসেবল বনাম না হয়ে ক্লাস করার সুবিধাটি বোঝাতে চাইছি। কীভাবে এর অর্থ ব্যাখ্যা করা যেতে পারে তা নিশ্চিত নন: এস
অ্যালিউরকোড 25:13

উত্তর:


159

আপনার প্রথম জিনিসটি সম্পর্কে জানা উচিত Cloneable- এটি ব্যবহার করবেন না।

Cloneableডান দিয়ে ক্লোনিং বাস্তবায়ন করা খুব কঠিন , এবং প্রচেষ্টাটির পক্ষে এটি কার্যকর নয়।

এর পরিবর্তে কিছু অন্যান্য বিকল্প যেমন অ্যাপাচি-কমন্স SerializationUtils(ডিপ-ক্লোন) বা BeanUtils(অগভীর-ক্লোন) ব্যবহার করুন বা কেবল একটি অনুলিপি-নির্মাণকারী ব্যবহার করুন।

ক্লোনিং সম্পর্কে জোশ ব্লচের মতামতের জন্য এখানে দেখুনCloneable , যা পদ্ধতির অনেকগুলি ত্রুটি ব্যাখ্যা করে। ( জোশুয়া ব্লচ একজন সান কর্মচারী ছিলেন এবং অসংখ্য জাভা বৈশিষ্ট্য বিকাশের নেতৃত্ব দিয়েছিলেন))


4
আমি ব্লচের কথাগুলি সংযুক্ত করেছি (সেগুলি উদ্ধৃত করার পরিবর্তে)
বোজহো

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

ইন্টারফেস সংজ্ঞায়িত করার সময় একটি অনুলিপি নির্মাণকারী বিকল্প কি? কেবল একটি অনুলিপি পদ্ধতি যুক্ত করবেন?
বেনজ

@ বেনেজ আমি হ্যাঁ বলব। জাভা -8 যেহেতু আপনার staticইন্টারফেসগুলিতে পদ্ধতি থাকতে পারে , তাই কেবল একটি সরবরাহ করবেন static WhatEverTheInterface copy(WhatEverTheInterface initial)? তবে আমি অবাক হই যে এটি আপনাকে কী দেয়, যেহেতু আপনি ক্লোন করার সময় কোনও বস্তু থেকে ক্ষেত্রগুলি অনুলিপি করেন তবে একটি ইন্টারফেস কেবলমাত্র পদ্ধতিগুলি সংজ্ঞায়িত করে। বোঝাতে যত্ন?
ইউজিন

40

ক্লোনযোগ্য নিজেই দুর্ভাগ্যক্রমে কেবল একটি চিহ্নিতকারী-ইন্টারফেস, এটি: এটি ক্লোন () পদ্ধতিটি সংজ্ঞায়িত করে না।

যা হয় তা হ'ল সুরক্ষিত অবজেক্ট.ক্লোন () পদ্ধতির আচরণ পরিবর্তন করা, যা ক্লোনেবেল বাস্তবায়ন করে না এমন ক্লাসগুলির জন্য ক্লোননটসপোর্টড এক্সপ্লেশন নিক্ষেপ করবে এবং যে ক্লাসগুলি করে তাদের জন্য সদস্য-ভিত্তিক অগভীর অনুলিপি সম্পাদন করবে।

এমনকি আপনি যদি এমন আচরণটি সন্ধান করছেন তা সত্ত্বেও, জনসাধারণের জন্য আপনার নিজের ক্লোন () পদ্ধতিটি এখনও প্রয়োগ করতে হবে।

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

এই পদ্ধতিটি এমন কোনও যুক্তিকে বাইপাস করে যা আপনার নির্মাতাদের মধ্যে সংজ্ঞায়িত করা যেতে পারে, যা সম্ভবত সমস্যাযুক্ত হতে পারে।

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

বেশিরভাগ বিকাশকারী এই কারণে ক্লোনযোগ্য ব্যবহার করেন না এবং এর পরিবর্তে কেবল একটি অনুলিপি নির্মাণকারীকে প্রয়োগ করেন।

ক্লোনেবেলের আরও তথ্য এবং সম্ভাব্য সমস্যাগুলির জন্য, আমি জোশুয়া ব্লুচের কার্যকর জাভা বইটি সুপারিশ করছি


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

সুতরাং, ক্লোনেবেলটি ন্যায়বিচারের সাথে ব্যবহার করুন। সমস্ত কিছু সঠিকভাবে করার জন্য আপনার যে প্রয়াস প্রয়োগ করতে হবে তার তুলনায় এটি আপনাকে পর্যাপ্ত সুবিধা দেয় না।


বোঝো যেমন বলেছিল, ক্লোনযোগ্য ব্যবহার করবেন না। পরিবর্তে, একটি অনুলিপি-নির্মাণকারী ব্যবহার করুন। javapractices.com/topic/TopicAction.do?Id=12
বেন

@ বেন, আপনি যদি ক্লোন করার জন্য অবজেক্টের ধরণটি জানেন না, তবে আপনি কীভাবে জানবেন কোন শ্রেণীর অনুলিপি নির্মাণকারীকে অনুরোধ করবেন?
স্টিভ কুও

@ স্টিভ: আমি অনুসরণ করি না আপনি যদি কোনও বস্তুর ক্লোন করতে চলেছেন তবে আমি অনুমান করি আপনি এটি ইতিমধ্যে জানেন যে এটি কী ধরণের - সর্বোপরি, আপনি যে ক্লোনিংয়ের পরিকল্পনা করছেন তা আপনার হাতে রয়েছে। এবং যদি এমন কোনও পরিস্থিতি হয় যেখানে আপনার অবজেক্টটি আরও সাধারণের কাছে নির্দিষ্ট ধরণের হয়ে গেছে, আপনি কোনও সাধারণ 'উদাহরণ' ব্যবহার করে তা মূল্যায়ন করতে পারবেন না ???
বেন

4
@ বেন: ধরুন আপনার কাছে টাইপ এ থেকে প্রাপ্ত সমস্ত বস্তুর একটি তালিকা রয়েছে, সম্ভবত 10 টি বিভিন্ন ধরণের রয়েছে। আপনি জানেন না যে প্রতিটি বস্তুর ধরণ কী। এই ক্ষেত্রে উদাহরণস্বরূপ ব্যবহার করা খুব খারাপ ধারণা। আপনি যদি অন্য ধরণের যোগ করেন, প্রতিবার আপনি এটি করার সময় আপনাকে অন্য একটি উদাহরণ পরীক্ষা যোগ করতে হবে। এবং, যদি উত্পন্ন ক্লাসগুলি অন্য প্যাকেজে থাকে তবে আপনি অ্যাক্সেস করতে পারবেন না? ক্লোনিং একটি সাধারণ প্যাটার্ন। হ্যাঁ, জাভা বাস্তবায়ন খারাপ, তবে এর চারপাশে অনেকগুলি উপায় রয়েছে যা ঠিক কাজ করবে। একটি অনুলিপি নির্মাণকারী সমতুল্য ক্রিয়াকলাপ নয়।
চার্লস

@ চার্লস: কোনও বিশদ-উদাহরণের অভাবে এবং এই ধরণের সমস্যার মোকাবিলা করার ক্ষেত্রে সাম্প্রতিক অভিজ্ঞতার অভাবে, আমাকে ব্লচের কাছে পিছনে যেতে হবে। আইটেম # 11। এটি দীর্ঘ এবং কিছুটা শক্তভাবে পড়া, তবে এটি মূলত বলেছে "আপনি যখনই পারেন ক্লোনযোগ্য এড়ান, অনুলিপি নির্মাণকারীরা আপনার বন্ধু" "
বেন

7

ক্লোনিং একটি প্রাথমিক প্রোগ্রামিং দৃষ্টান্ত। জাভা বিভিন্নভাবে এটি খারাপভাবে প্রয়োগ করেছে এই সত্যটি ক্লোনিংয়ের প্রয়োজনীয়তা একেবারেই হ্রাস করে না। এবং, ক্লোনিং কার্যকর করা সহজ যা আপনি কাজ করতে চান, অগভীর, গভীর, মিশ্রিত যাই হোক না কেন এটি কার্যকর হবে। আপনি এমনকি ফাংশনটির জন্য নাম ক্লোন ব্যবহার করতে পারেন এবং পছন্দ করতে চাইলে ক্লোননেবল প্রয়োগ করতে পারবেন না।

ধরুন আমার কাছে A, B, এবং C ক্লাস রয়েছে, যেখানে B এবং C এ থেকে উদ্ভূত হয়েছে, যদি আমার কাছে এ জাতীয় টাইপের বস্তুর একটি তালিকা থাকে:

ArrayList<A> list1;

এখন, সেই তালিকায় এ, বি, বা সি টাইপের অবজেক্ট থাকতে পারে আপনি জানেন না কী কী ধরণের জিনিসগুলি। সুতরাং, আপনি তালিকাটি এইভাবে অনুলিপি করতে পারবেন না:

ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
    list2.add(new A(a));
}

যদি বস্তুটি আসলে বি বা সি টাইপের হয় তবে আপনি সঠিক কপিটি পাবেন না। এবং, যদি এ বিমূর্ত হয়? এখন, কিছু লোক এটির পরামর্শ দিয়েছেন:

ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
    if(a instanceof A) {
        list2.add(new A(a));
    } else if(a instanceof B) {
        list2.add(new B(a));
    } else if(a instanceof C) {
        list2.add(new C(a));
    }
}

এটি একটি খুব, খুব খারাপ ধারণা। আপনি যদি একটি নতুন উত্পন্ন প্রকার যুক্ত করেন? বি বা সি যদি অন্য কোনও প্যাকেজে থাকে এবং আপনার কাছে এই শ্রেণিতে অ্যাক্সেস নেই?

আপনি যা করতে চান তা হ'ল:

ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
    list2.add(a.clone());
}

ক্লোনটির বুনিয়াদী জাভা বাস্তবায়ন কেন সমস্যাযুক্ত তা প্রচুর লোক ইঙ্গিত করেছে। তবে, এটি সহজেই এইভাবে কাটিয়ে উঠতে পারে:

ক্লাস এ:

public A clone() {
    return new A(this);
}

বি শ্রেণিতে:

@Override
public B clone() {
    return new B(this);
}

সি ক্লাসে:

@Override
public C clone() {
    return new C(this):
}

আমি ক্লোনেবেল বাস্তবায়ন করছি না, কেবল একই ফাংশনটির নাম ব্যবহার করে। যদি আপনি এটি পছন্দ না করেন তবে এটির নাম দিন।


আমি পৃথক উত্তরে আপনার মন্তব্যের জবাব দেওয়ার পরে এটি দেখেছি; আমি দেখতে পাচ্ছি আপনি এখন কোথায় যাচ্ছেন তবে 2 টি জিনিস: 1) ওপি ক্লোনেবেল (ক্লোনিংয়ের জেনেরিক ধারণা সম্পর্কে নয়) ব্যবহার সম্পর্কে বিশেষভাবে জিজ্ঞাসা করেছিল, এবং 2) আপনি অনুলিপি তৈরির ক্ষেত্রে কিছুটা আলাদা করার চেষ্টা করছেন এবং ক্লোনিং এর জেনেরিক ধারণা। আপনি এখানে যে ধারণাটি পৌঁছেছেন তা বৈধ, তবে এর মূলে আপনি কেবল একটি অনুলিপি-নির্মাণকারী ব্যবহার করছেন। ;)
বেন

যদিও আমি বলতে চাই যে আমি এখানে আপনার পদ্ধতির সাথে একমত, এটি একটি # কপিরমথোড () অন্তর্ভুক্ত করার পরিবর্তে ব্যবহারকারীকে সরাসরি অনুলিপি-কন্সট্রাক্টরকে কল করতে বাধ্য করা।
বেন

5

ক) একটি অনুলিপি নির্মাণকারীর ওপরে ক্লোন এর পুরো অনেক সুবিধা নেই। সম্ভবত বৃহত্তমটি হ'ল সঠিক গতিশীল ধরণের একটি নতুন অবজেক্ট তৈরি করার ক্ষমতা (ঘোষিত প্রকারটি ক্লোনযোগ্য এবং গণ্য ক্লোন পদ্ধতি রয়েছে বলে ধরে নেওয়া)।

খ) ডিফল্ট ক্লোনটি একটি অগভীর অনুলিপি তৈরি করে এবং আপনার ক্লোন প্রয়োগের ক্ষেত্রে এটি পরিবর্তন না করা হলে এটি অগভীর অনুলিপি হিসাবে থাকবে। এটি কঠিন হতে পারে, বিশেষত যদি আপনার শ্রেণীর চূড়ান্ত ক্ষেত্র থাকে

বোঝো ঠিক, ক্লোন সঠিক হওয়া কঠিন হতে পারে। একটি অনুলিপি নির্মাণকারী / কারখানা সর্বাধিক প্রয়োজন পরিবেশন করবে।


0

ক্লোনযোগ্য অসুবিধাগুলি কি কি?

ক্লোনিংটি খুব বিপজ্জনক যদি আপনি অনুলিপি করছেন এমন বস্তুর গঠন রয়েছে। আপনাকে এই ক্ষেত্রে সম্ভাব্য পার্শ্ব প্রতিক্রিয়ার নীচে চিন্তা করতে হবে কারণ ক্লোন অগভীর অনুলিপি তৈরি করে:

ধরা যাক আপনার ডিবি সম্পর্কিত হেরফের পরিচালনা করার জন্য একটি জিনিস রয়েছে। বলুন, Connectionসম্পত্তিটির অন্যতম হিসাবে সেই বস্তুর اعتراض রয়েছে ।

সুতরাং কেউ যখন ক্লোন তৈরি করে originalObject, বস্তুটি তৈরি হচ্ছে, তখন বলুন cloneObject,। এখানে originalObjectএবং বস্তুর cloneObjectজন্য একই রেফারেন্স রাখা Connection

যাক অবজেক্টটি originalObjectবন্ধ করে দেয় Connection, সুতরাং এখন cloneObjectকাজ করবে না কারণ connectionবস্তুটি তাদের মধ্যে ভাগ করা হয়েছিল এবং এটি প্রকৃতপক্ষে বন্ধ করে দিয়েছিল originalObject

অনুরূপ সমস্যা দেখা দিতে পারে যদি আপনি যদি বলেন যে আপনি কোনও আইটেম হিসাবে আইওএসট্রিম রয়েছে এমন কোনও বিষয়টিকে ক্লোন করতে চান।

যদি বস্তুটি একটি যৌগিক বস্তু হয় তবে পুনরাবৃত্ত ক্লোনিং কীভাবে ঘটবে?

ক্লোনযোগ্য অগভীর অনুলিপি সম্পাদন করে। অর্থ হ'ল মূল অবজেক্ট এবং ক্লোন অবজেক্টের ডেটা একই রেফারেন্স / স্মৃতিতে নির্দেশ করবে। গভীর অনুলিপির ক্ষেত্রে বিপরীতে, মূল বস্তুর মেমরি থেকে প্রাপ্ত ডেটা ক্লোন অবজেক্টের মেমোরিতে অনুলিপি করা হয়।


আপনার শেষ অনুচ্ছেদটি খুব বিভ্রান্ত। Cloneableএকটি অনুলিপি না, Object.cloneনা। "আসল অবজেক্টের মেমরি থেকে প্রাপ্ত ডেটা ক্লোন অবজেক্টের মেমোরিতে অনুলিপি করা হয়" ঠিক কী তা Object.cloneকরে। গভীর অনুলিপি বর্ণনা করার জন্য আপনাকে রেফারেন্সযুক্ত বস্তুর স্মৃতি সম্পর্কে কথা বলতে হবে।
আইয়ুব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.