আমি কীভাবে ঠিক করব "ধরণের তালিকার এক্সপ্রেশনটির চেক না করা রূপান্তর প্রয়োজন ... '?


137

জাভা স্নিপেটে:

SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();

শেষ লাইনটি সতর্কতা উত্পন্ন করে

"ধরণের অভিব্যক্তিটির Listসাথে সামঞ্জস্য করার জন্য চেক না করা রূপান্তর প্রয়োজন List<SyndEntry>"

এটি ঠিক করার উপযুক্ত উপায় কী?

উত্তর:


96

যেহেতু getEntriesকোনও কাঁচা ফেরত দেয় তাই Listএটি যে কোনও কিছু রাখতে পারে।

সতর্কতা-মুক্ত পদ্ধতিটি একটি নতুন তৈরি করা List<SyndEntry>, তারপরে sf.getEntries()ফলাফলের প্রতিটি উপাদানটিকে SyndEntryআপনার নতুন তালিকায় যুক্ত করার আগে এটি কাস্ট করা । আপনার জন্য এই চেকিংটি Collections.checkedListকরে না - যদিও এটি করার জন্য এটি প্রয়োগ করা সম্ভব হত।

নিজের কাস্ট আপ সামনে রেখে, আপনি জাভা জেনেরিকের "ওয়্যারেন্টি শর্তাবলী মেনে চলছেন": যদি ClassCastExceptionউত্থাপিত হয় তবে এটি উত্স কোডের একটি কাস্টের সাথে যুক্ত হবে, সংকলক দ্বারা প্রবেশ করা কোনও অদৃশ্য কাস্ট নয়।


9
ধন্যবাদ - এটি "ওয়ারেন্টি" সম্পর্কে একটি আকর্ষণীয় অন্তর্দৃষ্টি এবং আমার নিজের কোডে স্পষ্টভাবে সম্পন্ন কাস্টের তুলনায় সংকলক দ্বারা করা অদৃশ্য কাস্ট।
ব্যবহারকারী 46277

1
হ্যাঁ, অ-সংশোধিত জেনেরিকের মান কিছুটা সীমাবদ্ধ তবে এটি একটি জিনিস যা এটি সরবরাহ করে। কেবল পরিষ্কার করতে, এটির জন্য আপনার কোডটি ধরণের সুরক্ষা সতর্কতা ছাড়াই সংকলন করতে হবে।
এরিকসন

হাই ইরিকসন, আমি সম্মতি দিচ্ছি যে এটি সত্যই সেরা সমাধান। এই সমাধানটির জেনেরিক সংস্করণের জন্য আমার উত্তর stackoverflow.com/questions/367626/… দেখুন ।
ব্রুনো ডি ফ্রেইন

115

প্রাক জাভা 5 এপিআইয়ের সাথে কাজ করার সময় এটি একটি সাধারণ সমস্যা। এরিকসন থেকে সমাধানটি স্বয়ংক্রিয় করতে, আপনি নিম্নলিখিত জেনেরিক পদ্ধতি তৈরি করতে পারেন:

public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
    List<T> r = new ArrayList<T>(c.size());
    for(Object o: c)
      r.add(clazz.cast(o));
    return r;
}

এটি আপনাকে করতে দেয়:

List<SyndEntry> entries = castList(SyndEntry.class, sf.getEntries());

কারণ এই সমাধানটি পরীক্ষা করে থাকে যে উপাদানগুলির প্রকৃতপক্ষে একটি castালাইয়ের মাধ্যমে সঠিক উপাদান টাইপ থাকে, এটি নিরাপদ, এবং এটির প্রয়োজন হয় না SuppressWarnings


5
ব্রুনো দ্বারা প্রস্তাবিত পদ্ধতি সম্পর্কে, অনেক উপাদানগুলির তালিকা থাকলে এই অ্যাপ্লিকেশন কার্যকারিতা ক্ষতিগ্রস্থ হতে পারে? জাভা তাদের প্রতিটি এবং প্রতিটি কাস্ট করতে হবে।
will824

2
আপনি যদি গ্যারান্টি চান তবে এটাই খরচ। অন্য কম ব্যয় বিকল্প আছে? স্পষ্টতই, যদি আপনার আহ্বান করা কাঁচা সংগ্রহ ফেরত দেওয়ার পদ্ধতির উপর নিয়ন্ত্রণ থাকে, বা এমনকি পদ্ধতিটি চাওয়া হয় বা অলস-চাহিদা পদ্ধতির সাহায্যে সংগ্রহটি অ্যাক্সেস করে। পদ্ধতি আহ্বানের পরে পুরো সংগ্রহটি বিবেচনা করে এমন কিছু?
ড্যান

28

দেখে মনে SyndFeedহচ্ছে জেনেরিক ব্যবহার করছে না।

আপনি হয় একটি অনিরাপদ castালাই এবং একটি সতর্কতা দমন করতে পারে:

@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();

অথবা কল Collections.checkedList - যদিও আপনি এখনও সতর্কবার্তা দমন করতে হবে:

@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);

যেহেতু তারা উভয়ই সতর্কতা দমন করে, এক বা অন্যটির কোনও সুবিধা, বা পছন্দ? ধন্যবাদ! এছাড়াও: যদি অচিহ্নবিহীন দমন জায়গায় থাকে তবে theালাই প্রয়োজনীয়?
ড্যান রোজনস্টার্ক

3
@ ইয়ার: ঠিক আছে, Collections.checkedListপরে কোনও অ-সিন্ড্রেট্রি উপাদান যুক্ত করা রোধ করবে। আমি ব্যক্তিগতভাবে checkedListখুব বেশি ব্যবহার করি না , তবে তারপরে আমি প্রায়শই যাইহোক যাইহোক এই অনির্দিষ্ট কাস্টের পরিস্থিতিতে getুকি না ...
জন স্কিইট

9

আপনি কি লিখেছেন SyndFeed?

না sf.getEntriesআসতে তালিকা বা List<SyndEntry>? আমার ধারণা এটি ফিরে আসে Listএবং এটির List<SyndEntry>পরিবর্তে সমস্যাটি ঠিক হয়ে যায়।

যদি SyndFeedকোনও লাইব্রেরির অংশ হয় তবে আমি মনে করি না যে আপনি @SuppressWarning("unchecked")আপনার পদ্ধতিতে টীকা যুক্ত না করে সতর্কতাটি সরাতে পারবেন ।


আপনি একটি সুস্পষ্ট কাস্ট যোগ করতে পারেন।
উরি

3
কোডটি নিরাপদ নয় বলে একটি কাস্ট কেবল অন্য সতর্কতা তৈরি করবে।
এরিকসন


2

আপনি যদি পেয়ারা ব্যবহার করছেন এবং আপনি যা করতে চান তা হ'ল আপনার মানগুলির মাধ্যমে পুনরাবৃত্তি:

for(SyndEntry entry: Iterables.filter(sf.getEntries(), SyndEntry.class){
  ...
}

আপনার যদি সত্যিকারের তালিকা প্রয়োজন হয় তবে আপনি ব্যবহার করতে পারেন

List<SyndEntry> list = Lists.newArrayList(
    Iterables.filter(sf.getEntries(), SyndEntry.class));

অথবা

List<SyndEntry> list = ImmutableList.copyOf(
    Iterables.filter(sf.getEntries(), SyndEntry.class));

1
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();

2
এমনকি এখানে প্রদত্ত কোড সমস্যাটি সমাধান করলেও আমি আপনাকে সংক্ষেপে এটি কেন তা কেন তা ব্যাখ্যা করতে উত্সাহিত করব। পোস্ট উত্তর কেন সমস্যার সমাধান করে দয়া করে তা ব্যাখ্যা করুন।
sbrattla

1

আপনি যদি ক্লাসের জাভাদোকটি দেখেন SyndFeed(আমি অনুমান করি আপনি ক্লাসটি উল্লেখ করছেন com.sun.syndication.feed.synd.SyndFeed), পদ্ধতিটি এন্ট্রি () প্রত্যাবর্তন করে না java.util.List<SyndEntry>, তবে কেবল ফিরে আসে java.util.List

সুতরাং এটির জন্য আপনার একটি সুস্পষ্ট কাস্ট দরকার।


0

আপনি যদি প্রতিটি sf.getEntries () কলটিতে @ সাপ্রেস ওয়ার্নিং ("চেক না করা") রাখতে চান না, আপনি সর্বদা একটি মোড়ক তৈরি করতে পারেন যা তালিকা ফিরে আসবে।

দেখুন এই অন্য প্রশ্ন


0

আরও সহজ

return new ArrayList<?>(getResultOfHibernateCallback(...))


তারপরে আপনি অ্যারেলিস্ট <?> এর প্রতিটি উপাদান ব্যবহারের সময় যথাযথ castালাই (পুনরায় কাস্টিং?) ব্যবহার করবেন।
ইনজিহিরে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.