আমি ভেবেছিলাম পার্কের বাইরে থেকে যাকে এটি মারতে চাইলে আমি এই সফটবলটি দেব। জেনেরিকগুলি কী কী, জেনেরিকের সুবিধাগুলি কী, কেন, কোথায়, কীভাবে আমি সেগুলি ব্যবহার করব? দয়া করে এটি মোটামুটি বেসিক রাখুন। ধন্যবাদ
আমি ভেবেছিলাম পার্কের বাইরে থেকে যাকে এটি মারতে চাইলে আমি এই সফটবলটি দেব। জেনেরিকগুলি কী কী, জেনেরিকের সুবিধাগুলি কী, কেন, কোথায়, কীভাবে আমি সেগুলি ব্যবহার করব? দয়া করে এটি মোটামুটি বেসিক রাখুন। ধন্যবাদ
উত্তর:
আমি নিজেকে পুনরাবৃত্তি করতে সত্যই ঘৃণা করি। আমার কাছে একই জিনিসটি প্রায়শই টাইপ করা ঘৃণা করি। আমি সামান্য পার্থক্য সহ জিনিসগুলি একাধিকবার পুনরায় বিশ্রাম দিতে পছন্দ করি না।
পরিবর্তে তৈরি করুন:
class MyObjectList {
MyObject get(int index) {...}
}
class MyOtherObjectList {
MyOtherObject get(int index) {...}
}
class AnotherObjectList {
AnotherObject get(int index) {...}
}
আমি একটি পুনরায় ব্যবহারযোগ্য শ্রেণি তৈরি করতে পারি ... (যে ক্ষেত্রে আপনি কোনও কারণে কাঁচা সংগ্রহটি ব্যবহার করতে চান না)
class MyList<T> {
T get(int index) { ... }
}
আমি এখন 3x আরও দক্ষ এবং আমার কেবল একটি অনুলিপি বজায় রাখতে হবে। আপনি কেন কম কোড বজায় রাখতে চান?
এটি অন্যান্য বা ক্লাসের সাথে ইন্টারঅ্যাক্ট করতে হবে এমন একটি Callable<T>
বা একটি হিসাবে সংগ্রহ না করা ক্লাসগুলির ক্ষেত্রেও সত্য Reference<T>
। আপনি কি প্রকৃতপক্ষে প্রসারিত করতে Callable<T>
এবং Future<T>
এবং অন্যান্য প্রতিটি সম্পর্কিত শ্রেণিকে টাইপ-নিরাপদ সংস্করণ তৈরি করতে চান?
আমি না।
টাইপকাস্ট করার প্রয়োজন নেই জাভা জেনেরিকের অন্যতম বড় সুবিধা , কারণ এটি সংকলন-সময়ে টাইপ চেকিং সম্পাদন করবে। এর সম্ভাবনা কমবেClassCastException
রানটাইমের সময় নিক্ষিপ্ত হতে এবং আরও দৃ rob় কোডের দিকে নিয়ে যেতে পারে।
তবে আমার সন্দেহ যে আপনি এ সম্পর্কে পুরোপুরি সচেতন।
প্রতিবার আমি জেনারিক্সের দিকে তাকাই এটি আমার মাথা ব্যাথা করে। আমি জাভার সেরা অংশটি দেখতে পেয়েছি এটি সরলতা এবং নূন্যতম সিনট্যাক্স এবং জেনারিকগুলি সহজ নয় এবং উল্লেখযোগ্য পরিমাণে নতুন সিনট্যাক্স যুক্ত করে।
প্রথমদিকে, আমি জেনেরিকের সুবিধাও দেখিনি। আমি জাভা শিখতে শুরু করেছিলাম 1.4 সিনট্যাক্স থেকে (যদিও জাভা 5 তখন বাইরে ছিল) এবং যখন আমি জেনেরিকের মুখোমুখি হয়েছিলাম তখন অনুভব করেছি যে এটি লেখার জন্য আরও কোড ছিল এবং আমি সত্যিই এর সুবিধাগুলি বুঝতে পারি নি।
আধুনিক আইডিই জেনারিক সহ রাইটিং কোডটিকে সহজ করে তোলে।
বেশিরভাগ আধুনিক, শালীন আইডিই জেনারিক সহ বিশেষত কোড সমাপ্তির সাথে কোড লেখার ক্ষেত্রে সহায়তা করার জন্য যথেষ্ট স্মার্ট।
এখানে একটি তৈরীর একটি উদাহরণ Map<String, Integer>
একটি সঙ্গে HashMap
। আমার যে কোডটি টাইপ করতে হবে তা হ'ল:
Map<String, Integer> m = new HashMap<String, Integer>();
এবং প্রকৃতপক্ষে, এটি কেবল নতুন তৈরি করতে অনেকগুলি টাইপ করতে হবে HashMap
। যাইহোক, বাস্তবে, গ্রহনটি আমার কী প্রয়োজন তা জানার আগে আমাকে কেবল এটি অনেকটাই টাইপ করতে হয়েছিল:
Map<String, Integer> m = new Ha
Ctrl+Space
সত্য, আমার নির্বাচন করা দরকার ছিল HashMap
প্রার্থীদের তালিকা থেকে , তবে মূলত আইডিই জেনেরিক প্রকারগুলি সহ কী যুক্ত করতে হবে তা জানত। সঠিক সরঞ্জামগুলির সাহায্যে জেনেরিক ব্যবহার খুব খারাপ নয়।
এছাড়াও, যেহেতু প্রকারগুলি জানা যায়, জেনেরিক সংগ্রহ থেকে উপাদানগুলি পুনরুদ্ধার করার সময়, আইডিই কাজ করবে যে এটি ইতিমধ্যে তার ঘোষিত প্রকারের একটি অবজেক্ট - আইডিইটির জন্য বস্তুর প্রকারের কী তা জানার প্রয়োজন নেই cast হয়
জেনারিক্সের মূল সুবিধাটি নতুন জাভা 5 বৈশিষ্ট্যগুলির সাথে ভালভাবে খেলতে আসে from একটিতে পূর্ণসংখ্যা টস করার Set
এবং এর মোট গণনা করার উদাহরণ এখানে রয়েছে :
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(42);
int total = 0;
for (int i : set) {
total += i;
}
কোডটির এই টুকরোতে, নতুন তিনটি জাভা 5 বৈশিষ্ট্য উপস্থিত রয়েছে:
প্রথমত, জেনেরিকস এবং আদিমতার অটোবক্সিং নিম্নলিখিত লাইনগুলিকে অনুমতি দেয়:
set.add(10);
set.add(42);
পূর্ণসংখ্যাটির মান সহ 10
একটি অটোবক্স হয় । (এবং একই জন্য )। তারপরে এটি টস করা হয় যা এসকে ধরে রাখে । একটি মধ্যে নিক্ষেপ করার চেষ্টাInteger
10
42
Integer
Set
Integer
String
একটি সংকলন ত্রুটির সৃষ্টি করে।
পরবর্তী, প্রতিটি লুপের জন্য এটি তিনটিই নেয়:
for (int i : set) {
total += i;
}
প্রথমত, Set
ধারণকারী Integer
করা একটি জন্য-প্রতিটি লুপ ব্যবহার করা হয়। প্রতিটি উপাদানকে একটি হিসাবে ঘোষণা করা int
হয় এবং Integer
এটি আদিমকে আনবক্সড না হওয়ার কারণে অনুমোদিত int
। আর এটা সত্য যে এই আনবক্সিং ঘটে পরিচিত কারণ জেনেরিক্স সেখানে যাঁরা ছিল উল্লেখ করার জন্য ব্যবহার করা হয়েছিল Integer
অনুষ্ঠিত গুলিSet
।
জেনেরিক্সগুলি আঠালো হতে পারে যা জাভা 5 এ প্রবর্তিত নতুন বৈশিষ্ট্যগুলি একত্রিত করে এবং এটি কোডিংকে আরও সহজ এবং নিরাপদ করে তোলে। এবং বেশিরভাগ সময় আইডিই আপনাকে বেশ ভাল পরামর্শ দেওয়ার জন্য যথেষ্ট স্মার্ট, তাই সাধারণত এটি পুরোপুরি বেশি টাইপ করে না।
এবং সত্যই, হিসাবে দেখা যেতে পারে Set
উদাহরণ , আমি মনে করি যে জাভা 5 টি বৈশিষ্ট্য ব্যবহার করা কোডটি আরও সংক্ষিপ্ত এবং শক্তিশালী করে তুলতে পারে।
সম্পাদনা করুন - জেনেরিক ব্যতীত একটি উদাহরণ
Set
জেনেরিক ব্যবহার না করে উপরের উদাহরণের উদাহরণ নীচে দেওয়া হল। এটি সম্ভব তবে ঠিক মনোরম নয়:
Set set = new HashSet();
set.add(10);
set.add(42);
int total = 0;
for (Object o : set) {
total += (Integer)o;
}
(দ্রষ্টব্য: উপরের কোডটি সংকলনকালে অচিহ্নযুক্ত রূপান্তর সতর্কতা উত্পন্ন করবে))
নন-জেনেরিক সংগ্রহগুলি ব্যবহার করার সময়, সংগ্রহের মধ্যে যে ধরণের প্রবেশ করা হয় তা হ'ল ধরণের বস্তু Object
। অতএব, এই উদাহরণে, একটি সেট এডিট করা Object
হচ্ছে add
।
set.add(10);
set.add(42);
উপরের লাইনে, অটোবক্সিং চলছে - আদিম int
মান 10
এবং বস্তুগুলিতে 42
অটোবক্স করা হচ্ছে Integer
, যা যুক্ত করা হচ্ছে Set
। যাইহোক, মনে রাখবেন, Integer
অবজেক্টগুলি Object
গুলি হিসাবে পরিচালনা করা হচ্ছে , কারণ সংকলকটি কোন ধরণের Set
প্রত্যাশা করা উচিত তা জানতে সাহায্য করতে কোনও ধরণের তথ্য নেই ।
for (Object o : set) {
এটি গুরুত্বপূর্ণ যে অংশ। প্রতিটি লুপের জন্য কাজ করার কারণ হ'ল উপস্থিত থাকলে ইন্টারফেস Set
প্রয়োগ করে Iterable
যা Iterator
টাইপ তথ্য সহ একটি উপস্থিত করে। (Iterator<T>
, এটি।)
যাইহোক, কোন প্রকার তথ্য নেই সাল থেকে Set
একটি ফিরে আসবে Iterator
যা মান ফিরে আসবে Set
যেমন Object
s, এবং যে কেন উপাদানের ক্ষেত্রে জন্য-প্রতিটি লুপ উদ্ধার করা হচ্ছে আবশ্যক ধরনের হতেObject
।
এখন Object
থেকে এটি পুনরুদ্ধার করা হয়েছে Set
, Integer
সংযোজন সম্পাদন করার জন্য এটি ম্যানুয়ালি নিক্ষেপ করা প্রয়োজন :
total += (Integer)o;
এখানে, একটি typecast একটি থেকে সঞ্চালিত হয় Object
একটি থেকে Integer
। এই ক্ষেত্রে, আমরা জানি যে এটি সর্বদা কার্যকর হবে, তবে ম্যানুয়াল টাইপকাস্টিং আমাকে সর্বদা অনুভব করে যে এটি ভঙ্গুর কোড যা অন্য কোনও জায়গায় যদি একটি ছোটখাটো পরিবর্তন আনা হয় তবে এটি ক্ষতিগ্রস্থ হতে পারে। (আমি অনুভব করি যে প্রতিটি টাইপকাস্ট হবার একটি ClassCastException
অপেক্ষায় থাকে তবে আমি ডিগ্রেশন করি ...)
Integer
এখন একটি মধ্যে unboxed হয় int
এবং মধ্যে উপরন্তু সঞ্চালন করার অনুমতি দেওয়া int
পরিবর্তনশীল total
।
আমি আশা করি যে আমি জাভা 5 এর নতুন বৈশিষ্ট্যগুলি নন-জেনেরিক কোড সহ ব্যবহার করা সম্ভব, তবে এটি জেনেরিক সহ রাইটিং কোডের মতো পরিষ্কার এবং সোজা-ফরোয়ার্ড নয়। এবং, আমার মতে, জাভা 5-এ নতুন বৈশিষ্ট্যগুলির পুরো সদ্ব্যবহার করার জন্য, জেনেরিকগুলির সন্ধান করা উচিত, যদি খুব কমপক্ষে, রানটাইমের সময় ব্যতিক্রম ছড়িয়ে দেওয়ার জন্য অবৈধ টাইপকাস্টগুলি রোধ করতে সংকলন-সময়ের চেকগুলির অনুমতি দেয়।
আপনি জাভা বাগ ডেটাবেস অনুসন্ধান করতে ঠিক আগে 1.5 মুক্তি ছিল তাহলে আপনি সাত গুণ বেশি বাগ খুঁজে পেতে চাই NullPointerException
চেয়ে ClassCastException
। সুতরাং এটি মনে হয় না যে এটি বাগ বা সন্ধানের জন্য কমপক্ষে ত্রুটিগুলি খুঁজে পাওয়া খুব দুর্দান্ত বৈশিষ্ট্য little
আমার জন্য জেনেরিকের বিশাল সুবিধাটি হ'ল তারা কোড গুরুত্বপূর্ণ টাইপের তথ্যগুলিতে নথী করে । আমি যদি কোডটিতে নথিভুক্ত সেই ধরণের তথ্য না চাই, তবে আমি গতিশীল টাইপ করা ভাষা, বা কমপক্ষে আরও অন্তর্নিহিত টাইপের অনুক্রম সহ একটি ভাষা ব্যবহার করব।
কোনও সামগ্রীর সংগ্রহ নিজের কাছে রাখা কোনও খারাপ শৈলী নয় (তবে সাধারণ শৈলীটি কার্যকরভাবে এনক্যাপসুলেশন উপেক্ষা করা হয়)। এটি বরং আপনি যা করছেন তার উপর নির্ভর করে। জেনেরিকের সাথে সংগ্রহগুলি "অ্যালগরিদমগুলিতে" পাস করা চেক করা কিছুটা সহজ at
জাভা জেনেরিক্স প্যারামেট্রিক পলিমারফিজম সহজতর করে । টাইপ প্যারামিটারগুলির মাধ্যমে, আপনি প্রকারগুলিতে আর্গুমেন্টগুলি পাস করতে পারেন। String foo(String s)
মডেলগুলির মতো কোনও আচরণ যেমন কোনও আচরণের জন্য, কেবল কোনও নির্দিষ্ট স্ট্রিংয়ের জন্য নয়, তবে কোনও স্ট্রিংয়ের জন্য s
, তেমনি কোনও ধরণের List<T>
মডেল কিছু আচরণ করে, কেবল একটি নির্দিষ্ট ধরণের জন্য নয়, যে কোনও ধরণের জন্য । List<T>
বলছেন যে কোনো ধরনের জন্য T
, সেখানে এক ধরনের এর List
যার উপাদান T
গুলি । সুতরাং List
একটি প্রকৃতপক্ষে একটি নির্মাণকারী । এটি একটি ধরণের আর্গুমেন্ট হিসাবে গ্রহণ করে এবং ফলস্বরূপ অন্য ধরণের গঠন করে।
এখানে আমি প্রতিদিন ব্যবহার করি এমন জেনেরিক কয়েকটি উদাহরণ রয়েছে। প্রথমত, একটি খুব দরকারী জেনেরিক ইন্টারফেস:
public interface F<A, B> {
public B f(A a);
}
এই ইন্টারফেসটি বলে যে কিছু দুটি ধরণের জন্য, A
এবং B
, একটি ফাংশন রয়েছে (বলা হয় f
) যা গ্রহণ করে A
এবং ফিরে আসে a B
। আপনি যখন এই ইন্টারফেসটি বাস্তবায়ন করেন A
এবং B
যে কোনও ধরণের পছন্দসই হতে পারে, যতক্ষণ আপনি কোনও ফাংশন সরবরাহ করেন f
যা প্রাক্তনটি গ্রহণ করে এবং পরবর্তীটি ফিরিয়ে দেয়। ইন্টারফেসটির একটি বাস্তবায়ন উদাহরণ:
F<Integer, String> intToString = new F<Integer, String>() {
public String f(int i) {
return String.valueOf(i);
}
}
জেনেরিক্সের আগে, মূলশব্দটি ব্যবহার করে সাবক্লাসিং করে পলিমারফিজম অর্জন করা হয়েছিল extends
। জেনেরিক্স সহ, আমরা প্রকৃতপক্ষে সাবক্লাসিংয়ের কাজটি বাদ দিতে পারি এবং পরিবর্তে প্যারামেট্রিক পলিমারফিজম ব্যবহার করতে পারি। উদাহরণস্বরূপ, কোনও ধরণের হ্যাশ কোড গণনা করতে ব্যবহৃত একটি প্যারামিটারাইজড (জেনেরিক) শ্রেণি বিবেচনা করুন। অবজেক্ট.হ্যাশকোড () কে ওভাররাইড করার পরিবর্তে আমরা এর মতো জেনেরিক ক্লাস ব্যবহার করব:
public final class Hash<A> {
private final F<A, Integer> hashFunction;
public Hash(final F<A, Integer> f) {
this.hashFunction = f;
}
public int hash(A a) {
return hashFunction.f(a);
}
}
উত্তরাধিকার ব্যবহারের চেয়ে এটি অনেক বেশি নমনীয়, কারণ আমরা রন্ধনশৈলীর স্তরবিন্যাস লক না করে রচনা এবং প্যারামেট্রিক পলিমারফিজম ব্যবহারের থিমের সাথে থাকতে পারি।
জাভার জেনেরিকগুলি যদিও নিখুঁত নয়। আপনি প্রকারভেদে বিমূর্ত করতে পারেন তবে উদাহরণস্বরূপ আপনি টাইপ কনস্ট্রাক্টরগুলির উপর বিমূর্ত করতে পারবেন না। এটি, আপনি "যে কোনও টাইপের টির জন্য" বলতে পারেন, তবে আপনি "টাইপ প্যারামিটার এ জাতীয় যে কোনও ধরণের টির জন্য" বলতে পারেন না।
আমি এখানে জাভা জেনেরিকের এই সীমাগুলি সম্পর্কে একটি নিবন্ধ লিখেছিলাম।
জেনেরিক্সের সাথে একটি বিশাল জয় হল তারা আপনাকে সাবক্লাসিং এড়াতে দেয়। সাবক্লাসিংয়ের ফলে প্রজ্বলিত শ্রেণীর শ্রেণিবিন্যাসের প্রবণতা দেখা দেয় যা প্রসারিত হওয়া অবাস্তব এবং সম্পূর্ণ শ্রেণিবিন্যাসের দিকে না তাকিয়ে স্বতন্ত্রভাবে বুঝতে পারা ক্লাসগুলি।
জেনেরিক্স আগে Wereas তোমার মত শ্রেণীর থাকতে পারে Widget
প্রসারিত FooWidget
, BarWidget
এবং BazWidget
, জেনেরিক্স সঙ্গে আপনি একটি একক জেনেরিক বর্গ থাকতে পারে Widget<A>
যে একটি লাগে Foo
, Bar
বা Baz
তার কন্সট্রাকটর আপনাকে দিতে হবে Widget<Foo>
, Widget<Bar>
এবং Widget<Baz>
।
জেনারিকস বক্সিং এবং আনবক্সিংয়ের পারফরম্যান্স হিট এড়িয়ে চলে। মূলত, অ্যারেলিস্ট বনাম তালিকা <টি> দেখুন। উভয়ই একই মূল জিনিসগুলি করে তবে তালিকার <T> অনেক দ্রুত হবে কারণ আপনাকে অবজেক্টে / থেকে বাক্স করতে হবে না।
জেনারিক্সের সর্বোত্তম সুবিধা হ'ল কোড পুনরায় ব্যবহার। বলুন যে আপনার প্রচুর ব্যবসায়িক অবজেক্ট রয়েছে এবং একই ক্রিয়া সম্পাদন করার জন্য আপনি প্রতিটি সত্তার জন্য প্রচুর অনুরূপ কোড লিখতে চলেছেন। (IE লিনক থেকে এসকিউএল অপারেশন)।
জেনেরিকের সাহায্যে আপনি একটি শ্রেণি তৈরি করতে পারেন যা প্রদত্ত বেস শ্রেণীর উত্তরাধিকার সূত্রে প্রাপ্ত কোনও প্রকারের পরিচালনা করতে সক্ষম হবে বা প্রদত্ত ইন্টারফেসটি এর মতো প্রয়োগ করতে পারবে:
public interface IEntity
{
}
public class Employee : IEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeID { get; set; }
}
public class Company : IEntity
{
public string Name { get; set; }
public string TaxID { get; set }
}
public class DataService<ENTITY, DATACONTEXT>
where ENTITY : class, IEntity, new()
where DATACONTEXT : DataContext, new()
{
public void Create(List<ENTITY> entities)
{
using (DATACONTEXT db = new DATACONTEXT())
{
Table<ENTITY> table = db.GetTable<ENTITY>();
foreach (ENTITY entity in entities)
table.InsertOnSubmit (entity);
db.SubmitChanges();
}
}
}
public class MyTest
{
public void DoSomething()
{
var dataService = new DataService<Employee, MyDataContext>();
dataService.Create(new Employee { FirstName = "Bob", LastName = "Smith", EmployeeID = 5 });
var otherDataService = new DataService<Company, MyDataContext>();
otherDataService.Create(new Company { Name = "ACME", TaxID = "123-111-2233" });
}
}
উপরের ডোসোমিংথ পদ্ধতিতে বিভিন্ন ধরণের দেওয়া একই পরিষেবার পুনরায় ব্যবহারের বিষয়টি লক্ষ্য করুন। সত্যিই মার্জিত!
আপনার কাজের জন্য জেনেরিক ব্যবহার করার আরও অনেক দুর্দান্ত কারণ রয়েছে, এটি আমার প্রিয়।
আমি কেবল তাদের পছন্দ করি কারণ তারা আপনাকে একটি পছন্দসই ধরণের সংজ্ঞা দেওয়ার জন্য দ্রুত উপায় দেয় (যেমন আমি সেগুলি যেমন ব্যবহার করি)।
উদাহরণস্বরূপ উদাহরণস্বরূপ স্ট্রিং এবং একটি পূর্ণসংখ্যার সমন্বিত কোনও কাঠামো সংজ্ঞায়িত না করে এবং তারপরে কীভাবে এই কাঠামোগুলির একটি অ্যারে অ্যাক্সেস করতে হবে এবং কীভাবে আরও কিছু পদ্ধতিতে পদ্ধতি প্রয়োগ করা যায় তার পুরো সেটটি প্রয়োগ করে আপনি কেবল একটি অভিধান তৈরি করতে পারেন
Dictionary<int, string> dictionary = new Dictionary<int, string>();
এবং সংকলক / আইডিই ভারী উত্তোলনের বাকি অংশগুলি করে। বিশেষত একটি অভিধান আপনাকে প্রথম টাইপটি কী হিসাবে ব্যবহার করতে দেয় (পুনরাবৃত্ত মান নয়)।
টাইপযুক্ত সংগ্রহগুলি - এমনকি যদি আপনি সেগুলি ব্যবহার না করতে চান তবে আপনাকে অন্যান্য লাইব্রেরি, অন্যান্য উত্সগুলি থেকে তাদের মোকাবেলা করার সম্ভাবনা রয়েছে।
শ্রেণি তৈরিতে জেনেরিক টাইপিং:
পাবলিক ক্লাস ফু <টি> {পাবলিক টি পান () ...
কাস্টিং এড়ানো - আমি সবসময় পছন্দ মতো জিনিস অপছন্দ করি
নতুন তুলনাকারী {সর্বসাধারণের তুলনা তুলনা করুন (অবজেক্ট ও) {যদি (হে ক্লাসের যত্ন সম্পর্কে)
যেখানে আপনি মূলত এমন একটি শর্তের জন্য যাচাই করছেন যা কেবলমাত্র উপস্থিত হওয়া উচিত কারণ ইন্টারফেসটি অবজেক্টগুলির ক্ষেত্রে প্রকাশিত হয়।
জেনেরিকের প্রতি আমার প্রাথমিক প্রতিক্রিয়াটি আপনার মতই ছিল - "খুব অগোছালো, খুব জটিল"। আমার অভিজ্ঞতা হ'ল এগুলিকে কিছুটা ব্যবহারের পরে আপনি তাদের অভ্যস্ত হয়ে যান এবং সেগুলি ছাড়া কোড কম স্পষ্টভাবে নির্দিষ্ট, এবং কেবল কম স্বাচ্ছন্দ্য বোধ করে। এক্ষেত্রে, জাভা বিশ্বর বাকী অংশগুলি সেগুলি ব্যবহার করে যাতে আপনি শেষ পর্যন্ত প্রোগ্রামটি নিয়ে চলে যাবেন, তাই না?
একটি ভাল উদাহরণ দিতে। কল্পনা করুন আপনার ফু নামে একটি ক্লাস রয়েছে
public class Foo
{
public string Bar() { return "Bar"; }
}
উদাহরণ 1 এখন আপনি ফু অবজেক্টের একটি সংগ্রহ করতে চান। আপনার কাছে দুটি বিকল্প রয়েছে, এলআইএসটি বা অ্যারেলিস্ট, উভয়ই একই পদ্ধতিতে কাজ করে।
Arraylist al = new ArrayList();
List<Foo> fl = new List<Foo>();
//code to add Foos
al.Add(new Foo());
f1.Add(new Foo());
উপরের কোডে, যদি আমি ফু এর পরিবর্তে ফায়ারট্রাকের একটি শ্রেণি যুক্ত করার চেষ্টা করি, অ্যারেলিস্ট এটি যুক্ত করবে, তবে ফু এর জেনেরিক তালিকাটি ব্যতিক্রম ছুঁড়ে ফেলবে।
উদাহরণ দুটি।
এখন আপনার দুটি অ্যারে তালিকা রয়েছে এবং আপনি প্রতিটিটিতে বার () ফাংশনটি কল করতে চান। যেহেতু hte অ্যারেলিস্টটি অবজেক্টে পূর্ণ, আপনি বার কল করার আগে আপনাকে সেগুলি কাস্ট করতে হবে। তবে যেহেতু ফু-এর জেনেরিক তালিকায় কেবল ফুস থাকতে পারে, আপনি সরাসরি সেইগুলিতে বার () কল করতে পারেন।
foreach(object o in al)
{
Foo f = (Foo)o;
f.Bar();
}
foreach(Foo f in fl)
{
f.Bar();
}
আপনি কি কখনও কোনও পদ্ধতি (বা একটি শ্রেণি) লিখেছেন নি যেখানে পদ্ধতি / শ্রেণীর মূল ধারণাটি প্যারামিটার / উদাহরণ ভেরিয়েবলগুলির নির্দিষ্ট ডেটা ধরণের সাথে শক্তভাবে আবদ্ধ ছিল না (লিঙ্কযুক্ত তালিকা, সর্বাধিক / মিনিট ফাংশন, বাইনারি অনুসন্ধান ইত্যাদি))
আপনি কি চাননি যে আপনি কাট-এন-পেস্ট পুনরায় ব্যবহার বা দৃ or়-টাইপিংয়ের সাথে আপোস না করেই অ্যালগের্থম / কোডটি পুনরায় ব্যবহার করতে পারবেন (যেমন আমি List
স্ট্রিংগুলির একটি চাই , List
আমি আশা করি যে স্ট্রিংগুলি এমন জিনিস নয় !)?
কেন তুমি উচিত যে চান জেনেরিক্স (অথবা ভাল কিছু) ব্যবহার করতে।
ভুলে যাবেন না যে জেনেরিকগুলি কেবল ক্লাস দ্বারা ব্যবহৃত হয় না, সেগুলি পদ্ধতি দ্বারাও ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, নিম্নলিখিত স্নিপেট নিন:
private <T extends Throwable> T logAndReturn(T t) {
logThrowable(t); // some logging method that takes a Throwable
return t;
}
এটি সহজ, তবে খুব মার্জিতভাবে ব্যবহার করা যেতে পারে। সুন্দর জিনিস হ'ল পদ্ধতিটি যা দেওয়া হয়েছিল তা ফেরত দেয়। আপনি যখন কলারের কাছে আবার ছোঁড়াতে হবে এমন ব্যতিক্রমগুলি পরিচালনা করছেন তখন এটি আপনাকে সাহায্য করে:
...
} catch (MyException e) {
throw logAndReturn(e);
}
মুল বক্তব্যটি হ'ল কোনও পদ্ধতির মধ্য দিয়ে আপনি প্রকারটি হারাবেন না। আপনি ঠিক Throwable
একের পরিবর্তে সঠিক ধরণের ব্যতিক্রম ছুঁড়ে ফেলতে পারেন যা জেনারিক ব্যতীত আপনি যা করতে পারেন তা হবে।
এটি জেনেরিক পদ্ধতির জন্য একটি ব্যবহারের সহজ উদাহরণ। জেনেরিক পদ্ধতিতে আপনি করতে পারেন এমন বেশ কয়েকটি অন্যান্য ঝরঝরে জিনিস রয়েছে। সর্বোত্তম, আমার মতে, জেনেরিকগুলির সাথে টাইপ অনুমান করা। নিম্নলিখিত উদাহরণটি নিন (জোশ ব্লচের কার্যকর জাভা দ্বিতীয় সংস্করণ থেকে নেওয়া):
...
Map<String, Integer> myMap = createHashMap();
...
public <K, V> Map<K, V> createHashMap() {
return new HashMap<K, V>();
}
এটি খুব বেশি কিছু করে না, তবে জেনেরিক প্রকারগুলি দীর্ঘ (বা নেস্টেড; অর্থাত্ Map<String, List<String>>
) দীর্ঘ হলে এটি কিছু বিশৃঙ্খলা কেটে যায় ।
Throwable
কোনও মেথড বডি থেকে সাদামাটা পুরানো ফেলে দিতে পারবেন না যার নির্দিষ্ট ঘোষিত ব্যতিক্রম রয়েছে। বিকল্পটি হয় প্রতিটি ব্যাতিক্রমের প্রকারটি ফেরত দেওয়ার জন্য পৃথক পদ্ধতি রচনা করা, বা একটি নন-জেনেরিক পদ্ধতিতে নিজেকে কাস্ট করে যা এ Throwable
। পূর্ববর্তীটি খুব ভার্জোজ এবং বেশ অযথাযুক্ত এবং দ্বিতীয়টি সংকলকটির কাছ থেকে কোনও সহায়তা পাবে না। জেনেরিক ব্যবহার করে, সংকলক স্বয়ংক্রিয়ভাবে আপনার জন্য সঠিক কাস্ট inোকাবে। সুতরাং, প্রশ্নটি হচ্ছে: জটিলতার জন্য এটি কি মূল্যবান?
মিশেল যেভাবে উল্লেখ করেছে প্রাথমিক সুবিধা হ'ল একাধিক ক্লাস সংজ্ঞায়নের প্রয়োজন ছাড়াই শক্ত-টাইপিং।
এইভাবে আপনি স্টাফগুলি করতে পারেন:
List<SomeCustomClass> blah = new List<SomeCustomClass>();
blah[0].SomeCustomFunction();
জেনেরিকগুলি ব্যতীত আপনাকে ব্ল্যা [0] এর ফাংশনগুলি অ্যাক্সেস করার জন্য সঠিক টাইপ করতে হবে।
জেভিএম যাইহোক কাস্ট করে ... এটি স্পষ্টভাবে কোড তৈরি করে যা জেনেরিক ধরণেরটিকে "অবজেক্ট" হিসাবে বিবেচনা করে এবং পছন্দসই ইনস্ট্যান্টেশনে কাস্ট তৈরি করে। জাভা জেনেরিকস কেবল সিনট্যাকটিক চিনি।
আমি জানি এটি একটি সি # প্রশ্ন, তবে জেনেরিকগুলি অন্যান্য ভাষায়ও ব্যবহৃত হয় এবং তাদের ব্যবহার / লক্ষ্যগুলি বেশ মিল।
জাভা সংগ্রহগুলি জাভাগুলি 1.5 থেকে জাভাগুলি ব্যবহার করে । সুতরাং, আপনি যখন নিজের সংগ্রহের মতো কোনও বস্তু তৈরি করছেন তখন সেগুলি ব্যবহারের জন্য একটি ভাল জায়গা।
একটি উদাহরণ আমি প্রায় সব জায়গাতেই দেখতে পাই একটি জোড় শ্রেণি, যা দুটি বস্তু ধারণ করে, তবে জেনেরিক উপায়ে সেই বিষয়গুলি নিয়ে কাজ করা দরকার।
class Pair<F, S> {
public final F first;
public final S second;
public Pair(F f, S s)
{
first = f;
second = s;
}
}
আপনি যখনই এই জুটি ক্লাসটি ব্যবহার করেন আপনি কোন ধরণের অবজেক্টের সাথে ডিল করতে চান তা নির্দিষ্ট করতে পারেন এবং রানটাইমের পরিবর্তে যে কোনও ধরণের কাস্ট সমস্যাগুলি সংকলন সময়ে প্রদর্শিত হবে।
জেনারিকস তাদের সুপারিশগুলি 'সুপার' এবং 'এক্সটেন্ডস' কীওয়ার্ডগুলির সাহায্যে নির্ধারণ করতে পারে। উদাহরণস্বরূপ, আপনি যদি জেনেরিক প্রকারের সাথে ডিল করতে চান তবে আপনি এটি নিশ্চিত করতে চান যে এটি ফু নামে একটি শ্রেণীর প্রসারিত করে (যার একটি সেটটাইটেল পদ্ধতি রয়েছে):
public class FooManager <F extends Foo>{
public void setTitle(F foo, String title) {
foo.setTitle(title);
}
}
যদিও এটি নিজের পক্ষে খুব আকর্ষণীয় নয়, তবে এটি জেনে রাখা কার্যকর যে আপনি যখনই কোনও ফু ম্যানেজারের সাথে লেনদেন করেন, আপনি জানেন যে এটি মাইক্লাসের ধরণগুলি পরিচালনা করবে এবং মাইক্লাস ফু বাড়িয়ে দেয়।
"আমি জেনেরিক কেন ব্যবহার করব?" এর প্রতিক্রিয়া হিসাবে সান জাভা ডকুমেন্টেশন থেকে:
"জেনারিক্স আপনার সংগ্রহের প্রকারকে সংকলকের সাথে যোগাযোগের জন্য একটি উপায় সরবরাহ করে যাতে এটি পরীক্ষা করা যায় the সংকলকটি সংগ্রহের উপাদানটির ধরনটি একবার জানতে পেরে, সংকলকটি পরীক্ষা করে নিতে পারে যে আপনি সংগ্রহটি ধারাবাহিকভাবে ব্যবহার করেছেন এবং সন্নিবেশ করতে পারেন সংগ্রহের বাইরে মানগুলির সঠিক ক্যাসেটগুলি নেওয়া হচ্ছে ... জেনেরিকগুলি ব্যবহার করে কোডটি আরও পরিষ্কার এবং নিরাপদ .... সংকলকটি সংকলনের সময় যাচাই করতে পারে যে টাইপ সীমাবদ্ধতাগুলি রান চলাকালীন [জোর দেওয়া খনি] লঙ্ঘন করা হয়নি Because কারণ প্রোগ্রামটি সতর্কতা ছাড়াই সংকলন করে, আমরা নিশ্চিতভাবে বলতে পারি যে এটি রান সময়ে কোনও ক্লাসকাস্ট এক্সেকশন নিক্ষেপ করবে না gener জেনারিকগুলি ব্যবহারের, বিশেষত বড় প্রোগ্রামগুলিতে, পড়ার ক্ষমতা এবং দৃust়তা উন্নত হয় [[জোর দেওয়া]] "
জেনারিকস আপনাকে দৃ objects়ভাবে টাইপ করা অবজেক্ট তৈরি করার অনুমতি দেয়, তবুও আপনাকে নির্দিষ্ট ধরণের সংজ্ঞা দিতে হবে না। আমি মনে করি সর্বোত্তম দরকারী উদাহরণ হ'ল তালিকা এবং অনুরূপ শ্রেণি classes
জেনেরিক তালিকাটি ব্যবহার করে আপনি যা চান তা তালিকার তালিকার তালিকা থাকতে পারে এবং আপনি সবসময় শক্ত টাইপিংয়ের উল্লেখ করতে পারেন, আপনাকে কোনও অ্যারে বা স্ট্যান্ডার্ড তালিকার সাথে রূপান্তর করতে হবে বা আপনার মতো কিছু থাকতে হবে না।
জেনারিকস আপনাকে অবজেক্টস এবং ডেটা স্ট্রাকচারের জন্য শক্ত টাইপিং ব্যবহার করতে দেয় যা কোনও বস্তু ধরে রাখতে সক্ষম হবে। জেনেরিক স্ট্রাকচার (বক্সিং / আনবক্সিং) থেকে অবজেক্টগুলি পুনরুদ্ধার করার সময় এটি ক্লান্তিকর এবং ব্যয়বহুল টাইপকাস্টগুলিও সরিয়ে দেয়।
উভয় ব্যবহার করে এমন একটি উদাহরণ একটি লিঙ্কযুক্ত তালিকা। লিঙ্কযুক্ত তালিকার শ্রেণিটি কী হতে পারে যদি এটি কেবলমাত্র বস্তু ফু ব্যবহার করতে পারে? কোনও লিঙ্কযুক্ত তালিকা যা কোনও ধরণের অবজেক্টকে পরিচালনা করতে পারে তা বাস্তবায়নের জন্য, যদি আপনি তালিকায় কেবলমাত্র এক ধরণের অবজেক্ট থাকতে চান তবে লিঙ্কযুক্ত তালিকা এবং একটি অনুমান নোড অভ্যন্তর শ্রেণীর নোডগুলি অবশ্যই জেনেরিক হতে হবে।
জেনেরিক্স ব্যবহারের আরেকটি সুবিধা (বিশেষত সংগ্রহ / তালিকাগুলি সহ) আপনি টাইপ টাইপ চেক কমপাইল পান। বস্তুর তালিকার পরিবর্তে জেনেরিক তালিকা ব্যবহার করার সময় এটি সত্যই কার্যকর।
একমাত্র সর্বাধিক কারণ তারা প্রকার সুরক্ষা প্রদান করে
List<Customer> custCollection = new List<Customer>;
উল্টোদিকে,
object[] custCollection = new object[] { cust1, cust2 };
একটি সাধারণ উদাহরণ হিসাবে।
সংক্ষেপে, জেনেরিকগুলি আপনাকে কী করতে চান তা আরও সুনির্দিষ্টভাবে নির্দিষ্ট করতে দেয় (শক্তিশালী টাইপিং)।
এটি আপনার জন্য বিভিন্ন সুবিধা রয়েছে:
যেহেতু সংকলকটি আপনি কী করতে চান সে সম্পর্কে আরও জানেন, এটি আপনাকে প্রচুর টাইপ-কাস্টিং বাদ দিতে দেয় কারণ এটি ইতিমধ্যে জানে যে টাইপটি সামঞ্জস্যপূর্ণ হবে।
এটি আপনার প্রোগ্রামের সঠিক সম্পর্কিত সম্পর্কে আপনাকে পূর্ববর্তী প্রতিক্রিয়া জানায়। যে জিনিসগুলি আগে রানটাইমে ব্যর্থ হত (উদাহরণস্বরূপ কারণ কোনও বস্তু পছন্দসই ধরণের ক্ষেত্রে কাস্ট করা যায়নি), এখন সংকলন-সময় ব্যর্থ হয় এবং আপনার পরীক্ষা-বিভাগ একটি ক্রিপ্টিক্যাল বাগ রিপোর্ট ফাইল করার আগে আপনি ভুলটি ঠিক করতে পারেন।
সংকলকটি আরও অনুকূলকরণ করতে পারে, যেমন বক্সিং এড়ানো ইত্যাদি etc.
যোগ করার / প্রসারিত করার জন্য কয়েকটি জিনিস (। নেট দৃষ্টিভঙ্গি থেকে কথা বলা):
জেনেরিক প্রকারগুলি আপনাকে ভূমিকা ভিত্তিক ক্লাস এবং ইন্টারফেস তৈরি করতে দেয়। এটি ইতিমধ্যে আরও মৌলিক পদে বলা হয়েছে, তবে আমি আপনাকে আপনার কোডগুলি ক্লাসগুলির সাথে ডিজাইন করতে শুরু করেছি যা টাইপ-অজোনস্টিক উপায়ে প্রয়োগ করা হয় - যার ফলে অত্যন্ত পুনরায় ব্যবহারযোগ্য কোডের ফলস্বরূপ।
পদ্ধতিগুলিতে জেনেরিক যুক্তি একই কাজ করতে পারে তবে কাস্টিংয়ের ক্ষেত্রে তারা "বলুন না জিজ্ঞাসা করুন" নীতিটি প্রয়োগ করতে সহায়তা করে, অর্থাত "আমাকে যা চান তা আমাকে দিন, এবং যদি আপনি না পারেন তবে আপনি আমাকে কেন বলবেন"।
আমি এগুলিকে উদাহরণস্বরূপ স্প্রিংঅরএম এবং হাইবারনেটের সাথে বাস্তবায়িত জেনেরিকডাওতে ব্যবহার করি যা দেখতে এটির মতো
public abstract class GenericDaoHibernateImpl<T>
extends HibernateDaoSupport {
private Class<T> type;
public GenericDaoHibernateImpl(Class<T> clazz) {
type = clazz;
}
public void update(T object) {
getHibernateTemplate().update(object);
}
@SuppressWarnings("unchecked")
public Integer count() {
return ((Integer) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) {
// Code in Hibernate for getting the count
}
}));
}
.
.
.
}
জেনেরিক ব্যবহার করে আমার এই ডিএওগুলির বাস্তবায়নগুলি বিকাশকারীকে কেবল সত্তা জেনেরিকডাও সাবক্লাসিংয়ের মাধ্যমে ডিজাইন করা তাদের সত্তা পাস করার জন্য বাধ্য করে
public class UserDaoHibernateImpl extends GenericDaoHibernateImpl<User> {
public UserDaoHibernateImpl() {
super(User.class); // This is for giving Hibernate a .class
// work with, as generics disappear at runtime
}
// Entity specific methods here
}
আমার ছোট কাঠামোটি আরও দৃust় (ফিল্টারিং, অলস-লোডিং, অনুসন্ধানের মতো জিনিস রয়েছে)। আমি এখানে একটি সরলকরণ আপনাকে উদাহরণ দিতে
স্টিভ এবং আপনার মতো আমি শুরুতে বলেছিলাম "খুব অগোছালো এবং জটিল" তবে এখন আমি এর সুবিধাগুলি দেখতে পাচ্ছি
"প্রকার সুরক্ষা" এবং "কোনও কাস্টিং" এর মতো সুস্পষ্ট সুবিধাগুলি ইতিমধ্যে উল্লেখ করা হয়েছে তাই সম্ভবত আমি কিছু অন্যান্য "বেনিফিট" সম্পর্কে কথা বলতে পারি যা আশা করি এটি সহায়তা করে।
প্রথমত, জেনেরিক্স একটি ভাষা-স্বতন্ত্র ধারণা এবং আইএমও, আপনি যদি একই সময়ে নিয়মিত (রানটাইম) পলিমারফিজম সম্পর্কে চিন্তা করেন তবে এটি আরও বুদ্ধিমান হতে পারে।
উদাহরণস্বরূপ, পলিমারফিজম যেমন আমরা অবজেক্ট অরিয়েন্টেড ডিজাইন থেকে জানি তার একটি রানটাইম ধারণা রয়েছে যেখানে প্রোগ্রামার এক্সিকিউশন চলাকালীন কলার অবজেক্টটি রানটাইমের সময় খুঁজে পাওয়া যায় এবং প্রাসঙ্গিক পদ্ধতিটি রানটাইম টাইপের উপর নির্ভর করে কল করা হয়। জেনেরিক্সে, ধারণাটি কিছুটা অনুরূপ তবে সংকলনের সময় সবকিছু ঘটে। এর অর্থ কী এবং আপনি কীভাবে এটি ব্যবহার করবেন?
(আসুন জেনেরিক পদ্ধতির সাথে এটি কমপ্যাক্ট রাখার জন্য আটকে দিন) এর অর্থ হ'ল পৃথক ক্লাসে এখনও আপনার একই পদ্ধতি থাকতে পারে (যেমন আপনি আগে পলিমারফিক ক্লাসে করেছিলেন) তবে এবার সেগুলি সংকলক দ্বারা স্বয়ংক্রিয়ভাবে তৈরি করা হয়েছে সেটগুলির ধরণের উপর নির্ভর করে সংকলন সময়ে। সংকলনের সময় আপনি যে ধরণের প্রকারটি দেন তার উপর আপনি আপনার পদ্ধতিগুলি প্যারামিটারাইজ করেন। সুতরাং, রানটাইম পলিমারফিজমে (পদ্ধতি ওভাররাইডিং) আপনি যেমন করেন তেমন প্রতিটি প্রকারের জন্য স্ক্র্যাচ থেকে পদ্ধতিগুলি লেখার পরিবর্তে, সংকলনের সময় আপনি সংকলকগণ কাজটি করতে দেন। এটির একটি সুস্পষ্ট সুবিধা রয়েছে যেহেতু আপনার সিস্টেমে আপনার ব্যবহার করা হতে পারে এমন সমস্ত সম্ভাব্য প্রকারের অনুমানের দরকার নেই যা কোনও কোড পরিবর্তন ছাড়াই এটিকে আরও বেশি স্কেলেবল করে তোলে।
ক্লাসগুলি বেশ একইভাবে কাজ করে। আপনি টাইপটি পরামিতি করেন এবং কোডটি সংকলক তৈরি করে।
একবার আপনি "সংকলনের সময়" ধারণাটি পেয়ে গেলে আপনি "সীমাবদ্ধ" প্রকারগুলি ব্যবহার করতে পারেন এবং ক্লাস / পদ্ধতিগুলির মাধ্যমে প্যারাম্যাট্রিসড টাইপ হিসাবে কী পাস হতে পারে তা সীমাবদ্ধ করতে পারেন। সুতরাং, আপনি একটি শক্তিশালী জিনিস যা দিয়ে যেতে হবে তা নিয়ন্ত্রণ করতে পারেন বিশেষত আপনার কাঠামো অন্য লোকেরা গ্রাস করছে।
public interface Foo<T extends MyObject> extends Hoo<T>{
...
}
মাইবজেক্ট ছাড়া এখন আর কেউ স্টাথ সেট করতে পারে না।
এছাড়াও, আপনি আপনার পদ্ধতির আর্গুমেন্টগুলিতে টাইপ প্রতিবন্ধকতাগুলি "প্রয়োগ" করতে পারেন যার অর্থ আপনি নিশ্চিত করতে পারেন যে আপনার উভয় পদ্ধতি আর্গুমেন্ট একই ধরণের উপর নির্ভরশীল।
public <T extends MyObject> foo(T t1, T t2){
...
}
আশা করি এই সমস্ত কিছু বোধগম্য হয়।
আমি একবার এই বিষয়ে একটি বক্তৃতা দিয়েছি। আপনি আমার স্লাইডগুলি, কোড এবং অডিও রেকর্ডিংটি http://www.adventuresinsoftware.com/generics/ এ সন্ধান করতে পারেন ।
সংগ্রহের জন্য জেনেরিকগুলি ব্যবহার করা সহজ এবং পরিষ্কার। এমনকি আপনি অন্য কোথাও যদি এই বিষয়ে তর্ক করেন তবে সংগ্রহগুলি থেকে প্রাপ্ত লাভটি আমার কাছে জয়।
List<Stuff> stuffList = getStuff();
for(Stuff stuff : stuffList) {
stuff.do();
}
বনাম
List stuffList = getStuff();
Iterator i = stuffList.iterator();
while(i.hasNext()) {
Stuff stuff = (Stuff)i.next();
stuff.do();
}
বা
List stuffList = getStuff();
for(int i = 0; i < stuffList.size(); i++) {
Stuff stuff = (Stuff)stuffList.get(i);
stuff.do();
}
এটিই জেনেরিকের প্রান্তিক "ব্যয়" এর মূল্য, এবং এটি ব্যবহার করার জন্য এবং মূল্য পেতে আপনাকে জেনেরিক গুরু হতে হবে না।
জেনারিকস আপনাকে এখনও টাইপ নির্দিষ্ট সমর্থন সরবরাহ করার সময় আরও পুনরায় ব্যবহারযোগ্য বস্তু / পদ্ধতি তৈরি করার ক্ষমতা দেয়। আপনি কিছু ক্ষেত্রে প্রচুর পারফরম্যান্সও অর্জন করেন। আমি জাভা জেনেরিক্সের পুরো অনুমানটি জানি না, তবে। নেট মধ্যে আমি টাইপ প্যারামিটারের প্রতিবন্ধকতাগুলি যেমন ইন্টারফেস, কনস্ট্রাক্টর এবং ডেরিভেশন প্রয়োগ করতে পারি specify
প্রোগ্রামাররা জেনেরিক অ্যালগরিদমগুলি প্রয়োগ করতে সক্ষম করে - জেনেরিকগুলি ব্যবহার করে প্রোগ্রামাররা জেনেরিক অ্যালগরিদমগুলি প্রয়োগ করতে পারে যা বিভিন্ন ধরণের সংগ্রহগুলিতে কাজ করে, কাস্টমাইজ করা যায়, এবং টাইপ-নিরাপদ এবং পড়তে সহজ হয়।
সংকলনের সময়ে শক্তিশালী প্রকারের চেকগুলি - একটি জাভা সংকলক জেনেরিক কোডে দৃ type় ধরণের চেকিং প্রয়োগ করে এবং কোড প্রকারের সুরক্ষা লঙ্ঘন করলে ত্রুটি প্রদান করে। সংকলন-সময় ত্রুটিগুলি ঠিক করা রানটাইম ত্রুটিগুলি ঠিক করার চেয়ে সহজ, যা খুঁজে পাওয়া কঠিন difficult
জাতপাত নির্মূল।