আমি মাঝে মধ্যে শুনেছি জেনেরিক্স সহ জাভা এটি সঠিকভাবে পায় নি। (নিকটতম রেফারেন্স, এখানে )
আমার অনভিজ্ঞতা ক্ষমা করুন, তবে কী তাদের আরও ভাল করে তুলেছে?
আমি মাঝে মধ্যে শুনেছি জেনেরিক্স সহ জাভা এটি সঠিকভাবে পায় নি। (নিকটতম রেফারেন্স, এখানে )
আমার অনভিজ্ঞতা ক্ষমা করুন, তবে কী তাদের আরও ভাল করে তুলেছে?
উত্তর:
খারাপ:
List<byte>
প্রকৃত পক্ষে byte[]
উদাহরণস্বরূপ ব্যাক করা হয় এবং কোনও বক্সিং প্রয়োজন হয় না)ভাল:
সবচেয়ে বড় সমস্যাটি হ'ল জাভা জেনেরিকগুলি কেবল একটি সংকলনযুক্ত জিনিস এবং আপনি রান-টাইমে এটিকে বিকৃত করতে পারেন। সি # প্রশংসিত কারণ এটি আরও রান-টাইম চেকিং করে। এই পোস্টে কিছু সত্যিই ভাল আলোচনা আছে , এবং এটি অন্যান্য আলোচনার লিঙ্ক।
Class
চারপাশে বস্তুগুলি পাস করতে পারে ।
মূল সমস্যাটি হচ্ছে জাভাতে রানটাইমের সময় আসলে জেনারিক নেই। এটি একটি সংকলন সময় বৈশিষ্ট্য।
আপনি যখন জাভাতে জেনেরিক ক্লাস তৈরি করেন তখন তারা ক্লাস থেকে জেনেরিক ধরণের সমস্ত অপসারণের জন্য "টাইপ ইরেজর" নামক একটি পদ্ধতি ব্যবহার করে এবং প্রয়োজনীয়ভাবে তাকে বস্তুর সাথে প্রতিস্থাপন করে। জেনেরিক্সের মাইল উচ্চ সংস্করণ হ'ল সংকলকটি যখনই পদ্ধতিটির শরীরে প্রদর্শিত হয় তখন নির্দিষ্ট জেনেরিক প্রকারে কাস্টগুলি কেবল সন্নিবেশ করায়।
এতে অনেকটা ডাউনসাইড রয়েছে। সবচেয়ে বড় একটি, আইএমএইচও, আপনি জেনেরিক ধরণের পরিদর্শন করতে প্রতিবিম্বটি ব্যবহার করতে পারবেন না। প্রকারগুলি আসলে বাইট কোডে জেনেরিক হয় না এবং তাই জেনেরিক হিসাবে পরিদর্শন করা যায় না।
পার্থক্যগুলির এখানে দুর্দান্ত সংক্ষিপ্ত বিবরণ: http://www.jprl.com/Blog/archive/development/2007/Aug-31.html
(1) কিছু খুব অদ্ভুত আচরণ বাড়ে। আমি এর সেরা উদাহরণটি ভাবতে পারি। ধরে:
public class MyClass<T> {
T getStuff() { ... }
List<String> getOtherStuff() { ... }
}
তারপরে দুটি ভেরিয়েবল ঘোষণা করুন:
MyClass<T> m1 = ...
MyClass m2 = ...
এখন কল করুন getOtherStuff()
:
List<String> list1 = m1.getOtherStuff();
List<String> list2 = m2.getOtherStuff();
দ্বিতীয়টির জেনেরিক ধরণের আর্গুমেন্টটি সংকলকটি ছিনিয়ে নিয়েছে কারণ এটি একটি কাঁচা টাইপ (যার অর্থ প্যারামিটারাইজড টাইপ সরবরাহ করা হয় না) যদিও এর প্যারামিটারাইজড টাইপের সাথে কোনও সম্পর্ক নেই ।
আমি জেডিকে থেকে আমার প্রিয় ঘোষণার কথাও উল্লেখ করব:
public class Enum<T extends Enum<T>>
ওয়াইল্ডকার্ডিং (যা একটি মিশ্র ব্যাগ) ছাড়াও আমার মনে হয়। নেট জেনেরিকগুলি আরও ভাল।
public class Redundancy<R extends Redundancy<R>>
;)
The expression of type List needs unchecked conversion to conform to List<String>
Enum<T extends Enum<T>>
প্রথমে অদ্ভুত / অপ্রয়োজনীয় মনে হতে পারে তবে কমপক্ষে জাভা / এর জেনেরিকের সীমাবদ্ধতার মধ্যে এটি বেশ আকর্ষণীয়। এনামগুলির কাছে এনাম values()
হিসাবে টাইপ করা উপাদানগুলির একটি অ্যারে দেওয়ার একটি স্ট্যাটিক পদ্ধতি রয়েছে Enum
এবং এটি টাইপ জেনেরিক পরামিতি দ্বারা নির্ধারিত হয়, যার অর্থ আপনি চান Enum<T>
। অবশ্যই, সেই টাইপিংটি কেবল একটি গণনা করা প্রকারের প্রসঙ্গেই উপলব্ধি করে এবং সমস্ত এনামগুলি সাবক্লাস হয় Enum
, সুতরাং আপনি চান Enum<T extends Enum>
। তবে জাভা জেনেরিকের সাথে কাঁচা ধরণের মিশ্রণ পছন্দ করে না, এভাবে Enum<T extends Enum<T>>
ধারাবাহিকতার জন্য।
আমি একটি সত্যই বিতর্কিত মতামত ফেলে দিতে যাচ্ছি। জেনেরিক্স ভাষা জটিল করে কোড জটিল করে তোলে। উদাহরণস্বরূপ, ধরা যাক যে আমার কাছে একটি মানচিত্র রয়েছে যা স্ট্রিংয়ের তালিকার একটি স্ট্রিংকে মানচিত্র করে। পুরানো দিনগুলিতে, আমি এটিকে সহজ হিসাবে ঘোষণা করতে পারি
Map someMap;
এখন, আমি এটি হিসাবে ঘোষণা করতে হবে
Map<String, List<String>> someMap;
এবং যতবারই আমি এটি কোনও পদ্ধতিতে পাস করি, আমাকে আবার সেই দীর্ঘ দীর্ঘ ঘোষণার পুনরাবৃত্তি করতে হবে। আমার মতে, এই সমস্ত অতিরিক্ত টাইপিং বিকাশকারীকে বিরক্ত করে এবং তাকে "জোন" থেকে বাইরে নিয়ে যায়। এছাড়াও, কোডটি প্রচুর ক্রাফ্টে ভরা হয়ে গেলে, কখনও কখনও এটির পরে ফিরে আসা এবং গুরুত্বপূর্ণ যুক্তি সন্ধানের জন্য দ্রুত সমস্ত ক্রাফ্টের মধ্য দিয়ে সরিয়ে নেওয়া শক্ত হয়।
জাভা ইতিমধ্যে প্রচলিত ব্যবহারের মধ্যে সবচেয়ে ভার্বোজ ভাষা হওয়ায় একটি খারাপ খ্যাতি রয়েছে এবং জেনারিকরা কেবল সেই সমস্যাটিতে যুক্ত করে।
এবং এই অতিরিক্ত অতিরিক্ত ভারবসটির জন্য আপনি সত্যিই কি কিনবেন? স্ট্রিংসকে ধরে রাখার মতো কেউ যখন কোনও পূর্ণসংখ্যা স্থাপন করেছিল, বা যেখানে কোনও সংখ্যার স্ট্রিংটি স্ট্রিংগুলি বের করার চেষ্টা করেছে সেখানে আপনার সত্যিই কতবার সমস্যা হয়েছে? বাণিজ্যিক জাভা অ্যাপ্লিকেশন তৈরিতে কাজ করার আমার 10 বছরের অভিজ্ঞতায়, এটি কখনও কখনও ত্রুটির বড় উত্স হতে পারে নি। সুতরাং, অতিরিক্ত ভার্বোসটির জন্য আপনি কী পাচ্ছেন তা আমি সত্যিই নিশ্চিত নই। এটি সত্যিই আমাকে অতিরিক্ত আমলাতান্ত্রিক লাগেজ হিসাবে আঘাত করে।
এখন আমি সত্যিই বিতর্কিত হতে চলেছি। জাভা 1.4-এ সংগ্রহের ক্ষেত্রে আমি যেটি সবচেয়ে বড় সমস্যা হিসাবে দেখছি তা হ'ল সর্বত্র টাইপকাস্ট করার প্রয়োজনীয়তা। আমি সেই টাইপকাস্টগুলিকে অতিরিক্ত, ভার্বোস ক্রাফ্ট হিসাবে দেখি যা জেনেরিক্সের মতো একই সমস্যা রয়েছে। সুতরাং, উদাহরণস্বরূপ, আমি শুধু করতে পারি না
List someList = someMap.get("some key");
আমাকে করতে হবে
List someList = (List) someMap.get("some key");
অবশ্যই কারণটি হ'ল get () কোনও অবজেক্ট দেয় যা তালিকার একটি সুপার টাইপ। সুতরাং অ্যাসাইনমেন্টটি টাইপকাস্ট ছাড়া করা যাবে না। আবার, সেই নিয়ম আপনাকে সত্যিকার অর্থে কতটা কিনে তা ভেবে দেখুন। আমার অভিজ্ঞতা থেকে, খুব বেশি না।
আমি মনে করি জাভা যদি আরও ভাল হত তবে 1) এটি জেনেরিক যুক্ত না করে 2) পরিবর্তে একটি সুপার টাইপ থেকে সাব টাইপে অন্তর্নিহিত কাস্টিংয়ের অনুমতি দিত। রানটাইমের সময় ভুল ক্যাসেটগুলি ধরা যাক। তারপরে আমি সংজ্ঞায়নের সরলতা পেতে পারি
Map someMap;
এবং পরে করছেন
List someList = someMap.get("some key");
সমস্ত ক্রাফট চলে যাবে এবং আমি সত্যিই মনে করি না যে আমি আমার কোডে কোনও বড় বাগের উত্স প্রবর্তন করব।
এগুলির আর একটি পার্শ্ব প্রতিক্রিয়া হ'ল সংকলন-সময় এবং রান সময় না হ'ল আপনি জেনেরিক ধরণের কনস্ট্রাক্টরকে কল করতে পারবেন না। সুতরাং আপনি এগুলি জেনেরিক কারখানাটি প্রয়োগ করতে ব্যবহার করতে পারবেন না ...
public class MyClass {
public T getStuff() {
return new T();
}
}
--jeffk ++,
জাভা জেনেরিকগুলি সংকলনের সময় নির্ভুলতার জন্য পরীক্ষা করা হয় এবং তারপরে সমস্ত প্রকারের তথ্য মুছে ফেলা হয় (প্রক্রিয়াটিকে টাইপ ইরেজর বলা হয় Thus সুতরাং, জেনেরিকটি List<Integer>
তার কাঁচা প্রকারে কমিয়ে দেওয়া হবে , নন-জেনেরিকList
, যা স্বেচ্ছাসেবী শ্রেণীর অবজেক্টগুলি ধারণ করতে পারে।
এটি রানটাইমের সময় তালিকায় স্বেচ্ছাচারিত বস্তু সন্নিবেশ করতে সক্ষম হওয়ার ফলস্বরূপ, এখন জেনেরিক পরামিতি হিসাবে কী ধরণের ব্যবহৃত হত তা বলা এখন অসম্ভব। পরের ফলাফল ফলাফল
ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if(li.getClass() == lf.getClass()) // evaluates to true
System.out.println("Equal");
আমি ইচ্ছা করি এটি একটি উইকি ছিল যাতে আমি অন্য লোকের সাথে যুক্ত করতে পারি ... তবে ...
সমস্যা:
<
? মাইবজেক্টটি প্রসারিত করে>
[] , তবে আমার অনুমতি নেই)পুরো প্রকারের ক্ষয়জনিত জঞ্জাল উপেক্ষা করা, জেনারিকগুলি নির্দিষ্ট হিসাবে কেবল কাজ করে না।
এটি সংকলন:
List<Integer> x = Collections.emptyList();
তবে এটি একটি সিনট্যাক্স ত্রুটি:
foo(Collections.emptyList());
Foo যেখানে সংজ্ঞায়িত হয়েছে:
void foo(List<Integer> x) { /* method body not important */ }
সুতরাং কোনও এক্সপ্রেশন প্রকারের চেকগুলি স্থানীয় ভেরিয়েবলকে নির্ধারিত করা হচ্ছে বা কোনও পদ্ধতি কলের প্রকৃত প্যারামিটারের উপর নির্ভর করে কিনা। এ কেমন পাগল?
জাভাতে জেনেরিকের প্রবর্তন একটি কঠিন কাজ ছিল কারণ স্থপতিরা কার্যকরীতা, ব্যবহারের সহজতা এবং উত্তরাধিকারের কোডের সাথে পশ্চাদপটে সামঞ্জস্যের ভারসাম্য বজায় রাখার চেষ্টা করছিলেন। বেশ আশা করা যায়, আপস করতে হয়েছিল।
কিছু এমনও আছেন যারা মনে করেন যে জেনারিকের জাভা প্রয়োগের ফলে ভাষাটির জটিলতা অগ্রহণযোগ্য পর্যায়ে বৃদ্ধি পেয়েছে (কেন আর্নল্ডের " জেনারিকসকে ক্ষতিকারক বিবেচনা করা হয়েছে " দেখুন)। অ্যাঞ্জেলিকা ল্যাঙ্গারের জেনেরিক্সের প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী জটিল জিনিসগুলি কীভাবে পরিণত হতে পারে সে সম্পর্কে একটি দুর্দান্ত ধারণা দেয়।
জাভা রান সময় জেনেরিক্স প্রয়োগ করে না, শুধুমাত্র সংকলন সময়।
এর অর্থ হ'ল জেনেরিক সংগ্রহগুলিতে আপনি ভুল ধরণের যুক্ত করার মতো আকর্ষণীয় কাজ করতে পারেন।
জাভা জেনেরিকগুলি কেবল সংকলনযুক্ত এবং অ-জেনেরিক কোডে সংকলিত হয়। সি # তে প্রকৃত সংকলিত এমএসআইএল জেনেরিক। পারফরম্যান্সের জন্য এটির বিশাল প্রভাব রয়েছে কারণ জাভা এখনও রানটাইম চলাকালীন কাস্ট করে। আরও জন্য এখানে দেখুন ।
আপনি যদি জাভা পোস্ট # 279 শুনেন - জো ডারসি এবং অ্যালেক্স বাকলির সাথে সাক্ষাত্কার , তারা এই সমস্যাটি নিয়ে কথা বলে। এটি জাভা জন্য রিফাইড জেনারিকস শিরোনামে একটি নিল গিফের্ট ব্লগ পোস্টের সাথেও লিঙ্ক করেছে যা বলে:
জাভাতে জেনেরিকগুলি যেভাবে প্রয়োগ করা হয় তার ফলে সৃষ্ট বিধিনিষেধের সাথে অনেক লোক অসন্তুষ্ট। বিশেষত, তারা অসন্তুষ্ট যে জেনেরিক ধরণের পরামিতিগুলি পুনরায় সংশোধিত হয় না: রানটাইম এ সেগুলি উপলভ্য নয়। জেনেরিকগুলি ক্ষয় ব্যবহার করে প্রয়োগ করা হয়, যার মধ্যে জেনেরিক ধরণের পরামিতিগুলি রানটাইমগুলিতে কেবল সরানো হয়।
এই ব্লগ পোস্টটি, পুরানো এন্ট্রিটি উল্লেখ করে, ইরেজারের মাধ্যমে ধাঁধা: উত্তর বিভাগ , যা প্রয়োজনীয়তার মধ্যে মাইগ্রেশন সামঞ্জস্যতার বিষয়ে জোর দিয়েছিল ।
লক্ষ্যটি ছিল উত্স এবং অবজেক্ট কোড উভয়েরই পিছনের দিকের সামঞ্জস্যতা এবং মাইগ্রেশন সামঞ্জস্য।