জাভা: (স্ট্রিং []) লিস্ট.টোরআরে () ক্লাসকাস্টএক্সসেপশন দেয়


107

নিম্নলিখিত কোডটি (অ্যান্ড্রয়েডে চালিত) সর্বদা আমাকে তৃতীয় লাইনে ক্লাসকাস্টএক্সপশন দেয়:

final String[] v1 = i18nCategory.translation.get(id);
final ArrayList<String> v2 = new ArrayList<String>(Arrays.asList(v1));
String[] v3 = (String[])v2.toArray();

এটি যখন ভি 2 হ'ল অবজেক্ট [0] হয় এবং যখন স্ট্রিংগুলি থাকে তখনও এটি ঘটে। কোন আইডিয়া কেন?


- তুমি সহভেদাংক এবং Contravariance সম্পর্কে পড়তে পারেন en.wikipedia.org/wiki/...
Hut8

টি তখন ইনস্ট্যান্টেশনের জন্য কারখানার পদ্ধতি সহ একটি ইন্টারফেস, সেই ক্ষেত্রে কী হবে।
সেবাজ

2
@ লেসকার্ড - এটি কেবল পরোক্ষভাবে সংঘবদ্ধতা / বিপরীতে সম্পর্কিত। আসল বিষয়টি হ'ল toArray()পদ্ধতিটির নির্দিষ্ট আচরণের এটি প্রত্যক্ষ পরিণতি ।
স্টিফেন সি

উত্তর:


249

এটি কারণ আপনি যখন ব্যবহার

 toArray() 

এটি একটি অবজেক্ট [] প্রদান করে, যা কোনও স্ট্রিংয়ে কাস্ট করা যায় না [] (এমনকি বিষয়বস্তুগুলি স্ট্রিংসও হয়) এটি কারণ টোআরাই পদ্ধতিটি কেবল একটি পায়

List 

এবং না

List<String>

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

ব্যবহার

toArray(new String[v2.size()]);

যা সঠিক ধরণের অ্যারে (স্ট্রিং [] এবং সঠিক আকারের) বরাদ্দ করে



2
@ কালেব - সত্য নয় বা কমপক্ষে এটি মূল কারণ নয়। toArrayপদ্ধতি সামনে সংগ্রহ শ্রেণীর অস্তিত্ব জেনেরিক ছিলেন।
স্টিফেন সি

10
এটি সঠিক সমাধান, তবে সঠিক ব্যাখ্যা নয়। আপনি অবজেক্ট [] ডাবল করতে [] কাস্ট করতে পারবেন না কারণ এটি একটি ভাষা বৈশিষ্ট্য, আরও কিছু নয়। জেনারিক্সের সাথে এটির কোনও সম্পর্ক নেই। আপনি অবজেক্টকে ডাবল কাস্ট করতে পারেন ধরে নিলেন এটি সত্যই একটি ডাবল। সুতরাং যৌক্তিকভাবে, আপনি অ্যারে দিয়ে একই কাজ করতে পারেন, তবে এটি কেবল ভাষার অংশ নয়। আপনি যদি অবজেক্টকে ডাবল কাস্ট করেন তবে অবজেক্টটি আসলে দ্বিগুণ কিনা তা নিশ্চিত করার জন্য একটি রানটাইম চেক হবে। আপনি যদি ডাবল টু অবজেক্টে কাস্ট করেন তবে কোনও রানটাইম চেক নেই, যেহেতু অবজেক্টটি ডাবল এর উত্তরাধিকারক্রমক্রমে আছে।
কাইলিম

5
ইন্টেলিজজে এটি করার সময়, আমি toArray(new String[0])পরিবর্তে ব্যবহার করার জন্য একটি সতর্কতা পেয়েছি : "পুরানো জাভা সংস্করণগুলিতে প্রাক আকারের অ্যারে ব্যবহার করে পূর্ববর্তী জাভা সংস্করণগুলিতে সুপারিশ করা হয়েছিল কারণ যথাযথ আকারের অ্যারে তৈরি করা প্রয়োজনীয় প্রতিচ্ছবি কলটি বেশ ধীর ছিল। তবে ওপেনজেডকে-র শেষের আপডেটের পরে 6 এই কলটি সূচিত হয়েছিল, খালি অ্যারের সংস্করণটির পারফরম্যান্সটিকে একই এবং কখনও কখনও আরও উন্নত করে তোলে Also এছাড়াও প্রাক-আকারের অ্যারে পাস করা সমবর্তী সংগ্রহের জন্য বিপজ্জনক কারণ রেস sizeএবং toArrayকল করার মধ্যে একটি প্রতিযোগিতা সম্ভব ""
মাইকপোট

35

আপনি ভুল ব্যবহার করছেন toArray()

মনে রাখবেন যে জাভার জেনেরিকগুলি বেশিরভাগ সিনট্যাকটিক চিনি। একটি অ্যারেলিস্ট আসলে জানে না যে এর সমস্ত উপাদান স্ট্রিংস।

আপনার সমস্যা সমাধানের জন্য, কল করুন toArray(T[])। তোমার ক্ষেত্রে,

String[] v3 = v2.toArray(new String[v2.size()]);

নোট করুন যে জেনেরাইজড ফর্মটি toArray(T[])প্রত্যাবর্তন করে T[], তাই ফলাফলটি স্পষ্টভাবে বলার দরকার পড়ে না।


1
String[] v3 = v2.toArray(new String[0]); 

কৌতুকটিও করে, লক্ষ করুন যে একবার সঠিক অ্যারে টাইপ পদ্ধতিতে দেওয়া হয়ে গেলে আপনার আর কাস্ট করার দরকার নেই।


0
String[] str = new String[list.size()];
str = (String[]) list.toArray(str);

এই মত ব্যবহার করুন।


1
অনুগ্রহ! আপনার কোড ফর্ম্যাট করুন! এগুলির সবগুলি "ctrl + k" প্রেসে নির্বাচন করুন বা কোডের প্রথম বর্ণের আগে এবং শেষের দিকে অন্য একটিতে "another" যুক্ত করুন। উত্তর লেখার সময় আপনি উপরের সাহায্যে "{}" নির্বাচন করতে পারেন!
এমকে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.