1) জেনেরিকস এবং ভেরাগস সহ নির্দিষ্ট ইস্যু সম্পর্কে ইন্টারনেটে এবং স্ট্যাকওভারফ্লোতে প্রচুর উদাহরণ রয়েছে। মূলত, এটি যখন আপনার কাছে কোনও টাইপ-প্যারামিটার ধরণের আর্গুমেন্টের পরিবর্তনশীল থাকে:
<T> void foo(T... args);
জাভাতে, ভারারাগস একটি সিনট্যাকটিক চিনি যা সংকলন-সময়ে একটি সাধারণ "পুনরায় লেখার" মধ্য দিয়ে যায়: টাইপের একটি ভ্যারাগার্স পরামিতি টাইপের X...
একটি প্যারামিটারে রূপান্তরিত হয় X[]
; এবং প্রতিবার এই ভারার্গস পদ্ধতিতে যখন কোনও কল করা হয়, কম্পাইলারটি ভারেগেস প্যারামিটারে থাকা সমস্ত "ভেরিয়েবল আর্গুমেন্ট" সংগ্রহ করে এবং ঠিক ঠিক এর মতো একটি অ্যারে তৈরি করেnew X[] { ...(arguments go here)... }
।
যখন ভারার্গস টাইপটি কংক্রিটের মতো হয় তখন এটি ভালভাবে কাজ করে String...
। এটি যখন কোনও টাইপের ভেরিয়েবলের মতো হয় T...
, যখন T
সেই কলটির জন্য কংক্রিটের ধরণের হিসাবে পরিচিত হয় এটিও কাজ করে । যেমন যদি পদ্ধতি উপরে একটি বর্গ অংশ ছিল Foo<T>
, এবং আপনি একটি আছে Foo<String>
রেফারেন্স, তারপর কলিং foo
তে এটি কারণ আমরা জানি ঠিক আছে হবে T
হয়String
কোডে যে সময়ে।
যাইহোক, "মান" যখন T
অন্য ধরণের প্যারামিটার হয় তখন এটি কাজ করে না । জাভাতে, টাইপ-প্যারামিটার উপাদান টাইপের ( new T[] { ... }
) একটি অ্যারে তৈরি করা অসম্ভব । সুতরাং জাভা এর পরিবর্তে ব্যবহার করে new Object[] { ... }
(এখানে Object
উপরের সীমানাটি রয়েছে T
; যদি উপরের বাউন্ড কিছু আলাদা থাকে তবে তার পরিবর্তে এটি হবে Object
) এবং তারপরে আপনাকে একটি সংকলক সতর্কতা দেয়।
সুতরাং এর new Object[]
পরিবর্তে new T[]
বা যা কিছু তৈরি করে ভুল ? ওয়েল, জাভাতে অ্যারেগুলি রানটাইমের সময় তাদের উপাদানগুলির ধরনগুলি জানে। সুতরাং, পাস সময়কালে অ্যারে অবজেক্টের রানটাইমে ভুল উপাদান টাইপ থাকবে।
সম্ভবত উপাদানগুলির উপর পুনরাবৃত্তি করার জন্য, ভারার্গগুলির সর্বাধিক সাধারণ ব্যবহারের জন্য, এটি কোনও সমস্যা নয় (আপনি অ্যারের রানটাইম ধরণের বিষয়ে চিন্তা করেন না) তাই এটি নিরাপদ:
@SafeVarargs
final <T> void foo(T... args) {
for (T x : args) {
// do stuff with x
}
}
যাইহোক, পাস করা অ্যারের রানটাইম উপাদান উপাদান ধরণের উপর নির্ভর করে এমন কোনও কিছুর জন্য, এটি নিরাপদ হবে না। এটি অনিরাপদ এবং ক্র্যাশ হওয়া এমন একটি সাধারণ উদাহরণ:
class UnSafeVarargs
{
static <T> T[] asArray(T... args) {
return args;
}
static <T> T[] arrayOfTwo(T a, T b) {
return asArray(a, b);
}
public static void main(String[] args) {
String[] bar = arrayOfTwo("hi", "mom");
}
}
এখানে সমস্যা যে আমরা ধরনের উপর নির্ভর করে args
হতে T[]
অর্ডার যেমন আসতে হবে T[]
। তবে আসলে রানটাইমের সময় যুক্তির ধরণটি উদাহরণ নয় T[]
।
3) যদি আপনার পদ্ধতিতে টাইপের একটি আর্গুমেন্ট T...
(যেখানে টি কোনও ধরণের প্যারামিটার হয়), তবে:
- নিরাপদ: যদি আপনার পদ্ধতিটি কেবল অ্যারের উপাদানগুলির উদাহরণগুলির উপর নির্ভর করে
T
- অনিরাপদ: এটি অ্যারের উদাহরণ হিসাবে যদি এটি নির্ভর করে
T[]
অ্যারের রানটাইম টাইপের উপর নির্ভর করে এমন জিনিসগুলির মধ্যে রয়েছে: এটিকে টাইপ হিসাবে ফিরিয়ে দেওয়া, এটিকে টাইপের T[]
পরামিতি হিসাবে আর্গুমেন্ট হিসাবে পাস করা T[]
, অ্যারের টাইপটি ব্যবহার করে .getClass()
এটিকে রানটাইম টাইপের উপর নির্ভর করে এমন পদ্ধতিতে পাস করা, যেমন List.toArray()
এবংArrays.copyOf()
ইত্যাদি
2) আমি উপরে বর্ণিত পার্থক্যটি সহজেই স্বয়ংক্রিয়ভাবে আলাদা করা খুব জটিল।