জাভা 7-এ হীরা অপারেটরের (<>) বিন্দুটি কী?


445

জাভা 7-এ হীরা অপারেটর নীচের মত কোডের অনুমতি দেয়:

List<String> list = new LinkedList<>();

তবে জাভা 5/6 এ, আমি কেবল লিখতে পারি:

List<String> list = new LinkedList();

প্রকার মুছে ফেলার বিষয়ে আমার বোধগম্যতা হ'ল এগুলি ঠিক একই। (জেনেরিক যাইহোক রানটাইম এ সরানো হয়)।

কেন হীরা দিয়ে মোটেও বিরক্ত করবেন? এটি কোন নতুন কার্যকারিতা / ধরণের সুরক্ষা অনুমতি দেয়? যদি এটি কোনও নতুন কার্যকারিতা না দেয় তবে তারা কেন এটি বৈশিষ্ট্য হিসাবে উল্লেখ করেন? এই ধারণা সম্পর্কে আমার বোঝা ত্রুটিযুক্ত?


4
নোট করুন যে আপনি স্থিতিশীল কারখানার পদ্ধতিগুলি ব্যবহার করেন তবে এটি কোনও সমস্যা নয়, যেহেতু জাভা পদ্ধতিতে কলগুলিতে অনুমান টাইপ করে।
ব্রায়ান গর্ডন

আপনি যখন সতর্কতাটি অক্ষম করবেন এটি আসলে অকেজো ... :) আমার জন্য পছন্দ করুন
রিনিটিক

3
এটির উত্তর দেওয়া হয়েছে তবে এটি জাভা টিউটোরিয়ালেও রয়েছে (পৃষ্ঠার মাঝখানে): ডকস.অরাকল.com
অ্যান্ড্রেস তাসাউলাস

ডিজেনে এটি সম্পর্কে দুর্দান্ত নিবন্ধ ।
আর। ওস্টেরহল্ট

2
আমার এটির মতামত হল এটি << স্ট্রিং> তালিকার = নতুন লিংকডলিস্ট <বামদিকে টাইপ যাই হোক> () এর জন্য সিনট্যাকটিক চিনি; যেমন এটি জেনেরিক রাখা
ভিক্টর মেলগ্রেন

উত্তর:


496

বিষয়টি নিয়ে

List<String> list = new LinkedList();

এটি কি বাম দিকে, আপনি জেনেরিক টাইপটি ব্যবহার করছেন List<String>যেখানে ডানদিকে আপনি কাঁচা টাইপ ব্যবহার করছেন LinkedList। জাভাতে কাঁচা প্রকারগুলি কার্যকরভাবে পূর্ব-জেনেরিক কোডের সাথে সামঞ্জস্যের জন্য বিদ্যমান এবং আপনার সম্পূর্ণরূপে যদি না হয় তবে নতুন কোডে কখনই ব্যবহার করা উচিত নয়।

এখন, জাভা যদি প্রথম থেকেই জেনেরিকস থাকে এবং এর ধরণ না থাকে, যেমন LinkedList, জেনারিক হওয়ার আগে এটি মূলত তৈরি করা হয়েছিল, সম্ভবত এটি এটি তৈরি করতে পারত যাতে জেনেরিক ধরণের নির্মাতা স্বয়ংক্রিয়ভাবে বাম দিক থেকে তার ধরণের পরামিতিগুলি আবিষ্কার করে ers - যদি সম্ভব হয় তবে অ্যাসাইনমেন্টের পাশে। তবে এটি তা করেনি এবং পিছনের সামঞ্জস্যের জন্য এটি অবশ্যই কাঁচা ধরণের এবং জেনেরিক প্রকারকে আলাদাভাবে আচরণ করবে। এটি তাদের সামান্য আলাদা , তবে সমানভাবে সুবিধাজনক, জেনেরিক অবজেক্টের ধরণের পরামিতিগুলির পুনরাবৃত্তি না করে কোনও নতুন উদাহরণ ঘোষণার উপায়টি বজায় রাখে ... হীরা অপারেটর।

আপনার মূল উদাহরণ হিসাবে List<String> list = new LinkedList(), সংকলকটি এই নিয়োগের জন্য একটি সতর্কতা উত্পন্ন করে কারণ এটি অবশ্যই। এই বিবেচনা:

List<String> strings = ... // some list that contains some strings

// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);

জেনেরিকস ভুল কাজ করার বিরুদ্ধে সংকলন-সময় সুরক্ষা প্রদান করার জন্য বিদ্যমান। উপরের উদাহরণে, কাঁচা টাইপ ব্যবহার করার অর্থ আপনি এই সুরক্ষা পান না এবং রানটাইম এ ত্রুটি পাবেন। এজন্য আপনার কাঁচা ধরণের ব্যবহার করা উচিত নয়।

// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);

ডায়মন্ড অপারেটর, তবে, বাম পাশের মতো একই ধরণের প্যারামিটারগুলির সাথে অ্যাসাইনমেন্টের ডান হাতটিকে সত্য জেনেরিক উদাহরণ হিসাবে সংজ্ঞায়িত করার অনুমতি দেয় ... আবার সেই পরামিতিগুলি টাইপ না করেই। এটি আপনাকে কাঁচা টাইপ ব্যবহার করার মতো প্রায় একই প্রচেষ্টার সাথে জেনেরিকের সুরক্ষা রাখতে দেয় ।

আমি মনে করি মূল বিষয়টি বুঝতে হবে যে কাঁচা ধরণের (না সহ <>) জেনেরিক প্রকারের মতো চিকিত্সা করা যায় না। আপনি যখন কোনও কাঁচা প্রকার ঘোষণা করেন, আপনি জেনেরিকগুলির কোনও সুবিধা এবং টাইপ চেকিংয়ের কিছুই পাবেন না। আপনাকে এও মনে রাখতে হবে যে জেনেরিকগুলি জাভা ভাষার একটি সাধারণ উদ্দেশ্য অংশ ... তারা কেবলমাত্র নো-আর্গ নির্মাণকারীদের ক্ষেত্রে প্রয়োগ করে না Collection!


31
পিছনের সামঞ্জস্যতা দুর্দান্ত তবে জটিলতার ব্যয়ে নয় please জাভা 7 কেন কেবল -compatibilityসংকলক সুইচ চালু করতে পারেনি তবে যদি অনুপস্থিত থাকে তবে javacসমস্ত কাঁচা ধরণ নিষিদ্ধ করবে এবং কেবল জেনেরিক ধরণের কঠোরভাবে প্রয়োগ করবে? এটি আমাদের কোডগুলিকে যেমন কম ভার্বোস করে তুলবে।
রোসদী কাসিম

3
@ রসদী: সম্মত, নতুন কোডে কাঁচা ধরণের দরকার নেই। যাইহোক, আমি উত্স ফাইলটিতে জাভা সংস্করণ নম্বর (কমান্ড লাইন ব্যবহার করে (ভুল) পরিবর্তে) সহ দৃ strongly়ভাবে পছন্দ করব, আমার উত্তরটি দেখুন।
মার্টিনাস

37
আপনি ব্যক্তিগতভাবে হীরার ব্যবহার পছন্দ করেন না যদিও আপনি একই লাইনে সংজ্ঞা দিচ্ছেন এবং ইনস্ট্যান্ট করছেন। List<String> strings = new List<>()ঠিক আছে, তবে আপনি যদি সংজ্ঞায়িত করেন private List<String> my list;, এবং তারপরে আপনি যে পৃষ্ঠাটি দিয়ে ইনস্ট্যান্ট করেন তার অর্ধেক নীচে থাকে my_list = new List<>(), তবে এটি দুর্দান্ত নয়! আমার তালিকায় আবার কী রয়েছে? ওহ, সংজ্ঞাটির জন্য আমাকে ঘুরতে দাও হঠাৎ হীরার শর্টকাটের সুবিধাটি বিদায় নিল।
rmirabelle

11
@rmirabelle কিভাবে থেকে আলাদা: my_list = getTheList()? এই ধরণের সমস্যাগুলি কীভাবে মোকাবেলা করতে হয় তার জন্য আরও বেশ কয়েকটি আরও ভাল উপায় রয়েছে: ১. আইডিই ব্যবহার করুন যা মাউস হোভারের উপর আপনাকে বিভিন্ন ধরণের ভেরিয়েবল দেখায়। ২. আরও অর্থবহ ভেরিয়েবলের নাম ব্যবহার করুন, যেমন private List<String> strings3.. আপনার পরিবর্তন করতে না পারলে ভেরিয়েবলের ঘোষণা এবং আরম্ভের বিভাজন করবেন না।
ন্যাটিক্স

1
@ মরফিডন: হ্যাঁ, এটি এখনও জাভা ৮ এর জন্য বৈধ I'm আমি নিশ্চিত যে আপনাকে সতর্কতা দেওয়া উচিত
কলিনড

36

আপনার বোঝা কিছুটা ত্রুটিযুক্ত। হীরা অপারেটর একটি দুর্দান্ত বৈশিষ্ট্য কারণ আপনার নিজের নিজেকে পুনরাবৃত্তি করতে হবে না। আপনি যখন প্রকারটি ঘোষণা করেন তখন একবার প্রকারটি সংজ্ঞায়িত করা বোধগম্য হয় তবে ডানদিকে আবার এটি সংজ্ঞায়িত করার কোনও অর্থ হয় না। DRY নীতি।

ধরণের সংজ্ঞা নির্ধারণ সম্পর্কে সমস্ত অস্পষ্টতা ব্যাখ্যা করতে। আপনি ঠিক বলেছেন যে টাইপটি রানটাইমের সময় মুছে ফেলা হয়েছে তবে একবার আপনি টাইপ সংজ্ঞা সহ তালিকার বাইরে কিছু পেতে চাইলে তালিকাটি ঘোষণার সময় আপনি যে ধরণের সংজ্ঞা দিয়েছিলেন সেটি আবার ফিরে পাবেন অন্যথায় এটি সমস্ত নির্দিষ্ট বৈশিষ্ট্যগুলি হারাবে এবং কেবলমাত্র এতে থাকবে আপনি যখন পুনরুদ্ধারকৃত অবজেক্টটিকে মূল টাইপটিতে কাস্ট করতে চান তবে অবজেক্ট বৈশিষ্ট্যগুলি যা কখনও কখনও খুব কৌতুকপূর্ণ হতে পারে এবং ক্লাসকাস্টএক্সসেপশনের ফলস্বরূপ হতে পারে।

ব্যবহার List<String> list = new LinkedList()আপনি rawtype সতর্কবার্তা পাবেন।


8
List<String> list = new LinkedList()সঠিক কোড। আপনি এটি জানেন এবং আমি এটিও জানি। এবং প্রশ্নটি (যেমনটি আমি এটি বুঝতে পারি): কেন কেবল জাভা সংকলক বুঝতে পারে না যে এই কোডটি বেশ সুরক্ষিত?
রোমান

22
@Roman: List<String> list = new LinkedList()হয় না সঠিক কোড। অবশ্যই, এটি যদি ভাল হত! এটি সম্ভবত হতে পারে যদি জাভা প্রথম থেকেই জেনেরিকস থাকে এবং জেনেরিক ধরণের যে জেনেরিক হিসাবে ব্যবহৃত হত তার পিছনের সামঞ্জস্যতার সাথে মোকাবিলা করতে না হত, তবে তা হয়।
কলিনড

6
@ কলিনড জাভা প্রতিটি এক লাইনে পিছনের দিকের সামঞ্জস্যতার সাথে সত্যিই ডিল করার দরকার নেই । যে কোনও জাভা উত্স ফাইলটিতে জেনেরিকগুলি ব্যবহার করে পুরানো নন-জেনেরিক প্রকারগুলি নিষিদ্ধ করা উচিত ( <?>উত্তরাধিকারের কোডে ইন্টারফেসিং করা থাকলে আপনি সর্বদা ব্যবহার করতে পারেন) এবং অকেজো হীরা অপারেটরের অস্তিত্ব থাকা উচিত নয়।
মার্টিনাস

16

এই লাইনটি [চেক না করা] সতর্কতার কারণ করে:

List<String> list = new LinkedList();

সুতরাং, প্রশ্নটি রূপান্তরিত হয়: কেবল নতুন সংগ্রহ তৈরি হওয়ার সময় কেন [চেক করা নয়] সতর্কতা স্বয়ংক্রিয়ভাবে দমন করা হয় না?

আমি মনে করি, <>বৈশিষ্ট্য যুক্ত করার পরে এটি আরও অনেক কঠিন কাজ হবে ।

UPD : আমি আরও মনে করি যে যদি কাঁচা ধরণের 'কেবল কয়েকটি জিনিসের জন্য' ব্যবহার করা আইনত হয় তবে সেখানে কোনও হবে।


13

তত্ত্ব অনুসারে, ডায়মন্ড অপারেটর আপনাকে বারবার টাইপ করা যুক্তিগুলি সংরক্ষণ করে আরও কমপ্যাক্ট (এবং পঠনযোগ্য) কোড লেখার অনুমতি দেয়। অনুশীলনে, এটি কেবল দুটি বিভ্রান্তিকর চর এবং আপনাকে কিছুই দেয় না। কেন?

  1. কোনও বুদ্ধিমান প্রোগ্রামার নতুন কোডে কাঁচা ধরণের ব্যবহার করে না। সুতরাং সংকলকটি সহজেই ধরে নিতে পারে যে কোনও ধরণের আর্গুমেন্ট লিখে আপনি এটি নির্ধারণ করতে চান।
  2. হীরা অপারেটর কোনও প্রকারের তথ্য সরবরাহ করে না, এটি কেবল সংকলকটি বলে, "এটি ঠিক হয়ে যাবে"। সুতরাং এটিকে বাদ দিয়ে আপনি কোনও ক্ষতি করতে পারবেন না। হীরা অপারেটর বৈধ যে কোনও জায়গায় এটি সংকলক দ্বারা "অনুমান" করা যেতে পারে।

আইএমএইচও, একটি উত্সটি জাভা as হিসাবে চিহ্নিত করার একটি সুস্পষ্ট এবং সহজ উপায় থাকার সাথে এই জাতীয় উদ্ভট জিনিস আবিষ্কারের চেয়ে আরও কার্যকর হবে। চিহ্নিত চিহ্নিত কোডে কাঁচা ধরণের কিছু না হারিয়ে নিষেধ করা যেতে পারে।

বিটিডাব্লু।, আমি মনে করি না যে এটি একটি সংকলন সুইচ ব্যবহার করে করা উচিত। একটি প্রোগ্রাম ফাইলের জাভা সংস্করণ ফাইলের একটি বৈশিষ্ট্য, কোনও বিকল্প নেই। তুচ্ছ হিসাবে কিছু ব্যবহার

package 7 com.example;

এটি পরিষ্কার করে দিতে পারে (আপনি এক বা একাধিক অভিনব কীওয়ার্ড সহ আরও পরিশীলিত কিছু পছন্দ করতে পারেন)। এমনকি এটি কোনও সমস্যা ছাড়াই বিভিন্ন জাভা সংস্করণের জন্য লিখিত উত্সগুলি একত্রিত করার অনুমতি দেবে। এটি কোনও নতুন সামঞ্জস্যতা না হারিয়ে নতুন কীওয়ার্ডগুলি (যেমন, "মডিউল") প্রবর্তন করতে বা কিছু অপ্রচলিত বৈশিষ্ট্যগুলি (একক ফাইলে একাধিক অ-পাবলিক অ-নেস্টেড ক্লাসগুলি) ফেলে দেওয়ার অনুমতি দেয়।


2
আপনি new ArrayList(anotherList)এবং এর মধ্যে পার্থক্যটি বিবেচনা করেছেন new ArrayList<>(anotherList)(বিশেষত যদি এটি নির্ধারিত হয় List<String>এবং anotherListক হয় List<Integer>)?
পল বেলোরা

@ পল বেলোরা: না। অবাক করা বিষয় আমার জন্য, উভয়ই সংকলিত। হীরা দিয়ে যাওয়া এমনকি কোনও সতর্কতাও দেওয়া হয়নি। যাইহোক, আমি এর কোন ধারণা দেখতে পাচ্ছি না, আপনি কি বিস্তারিত বলতে পারবেন?
maaartinus

দুঃখিত, আমি খুব ভাল ব্যাখ্যা করিনি। এই দুটি উদাহরণের মধ্যে পার্থক্যটি দেখুন: আইডিয়োনা / ইয়ু হাগ এবং আইডিয়োন / এএনকেজি 3 টি আমি কেবল ইঙ্গিত করছি যে কমপক্ষে জেনেরিক সীমাবদ্ধতার সাথে যুক্তিগুলি পাস করার সময় কোনও কাঁচা টাইপের পরিবর্তে ডায়মন্ড অপারেটরটি ব্যবহার করা কোনও বিষয় নয় when ইন।
পল বেলোরা

আসলে আমি কলিনডির উত্তর পড়ার জন্য সময় নিইনি - তিনি একই জিনিসটির উল্লেখ করেছেন।
পল বেলোরা

2
সুতরাং, আমরা যদি কাঁচা ধরণের জন্য সত্যিই প্রয়োজনীয় কয়েকটি জায়গার জন্য একটি নতুন সিনট্যাক্স চালু করতে চলেছি তবে কেন এমন কিছু ব্যবহার করবেন না new @RawType List()। এটি ইতিমধ্যে বৈধ জাভা 8 সিনট্যাক্স এবং টাইপ টীকাগুলি এটি যেখানে প্রয়োজন সেখানে এটি ব্যবহারের অনুমতি দেয়, যেমন @RawType List = (@RawType List) genericMethod();। কাঁচা টাইপগুলি বর্তমানে কোনও সংকলন সতর্কতা তৈরি করে বিবেচনা করে যদি কোনও উপযুক্ত @SuppressWarningsস্থান না দেওয়া হয় তবে এটি @RawTypeএকটি যুক্তিসঙ্গত প্রতিস্থাপন হবে এবং আরও সূক্ষ্ম বাক্য গঠন প্রয়োজন হবে না।
হোলার

8

আপনি যখন লিখবেন List<String> list = new LinkedList();, সংকলক একটি "চেক না করা" সতর্কতা তৈরি করে। আপনি এটিকে এড়িয়ে যেতে পারেন, তবে আপনি যদি এই সতর্কতাগুলিকে উপেক্ষা করেন তবে আপনি একটি সতর্কতাও মিস করতে পারেন যা আপনাকে প্রকৃত ধরণের সুরক্ষা সমস্যা সম্পর্কে অবহিত করে।

সুতরাং, এমন কোনও কোড লেখা ভাল যা অতিরিক্ত সতর্কতা তৈরি করে না এবং ডায়মন্ড অপারেটর আপনাকে অপ্রয়োজনীয় পুনরাবৃত্তি না করে সুবিধাজনক উপায়ে এটি করতে দেয়।


4

অন্যান্য প্রতিক্রিয়াগুলিতে বলা সমস্ত বৈধ তবে ব্যবহারের কেসগুলি সম্পূর্ণ বৈধ আইএমএইচও নয়। যদি কেউ পেয়ারা এবং বিশেষত সংগ্রহ সম্পর্কিত জিনিসগুলি পরীক্ষা করে থাকে তবে স্থির পদ্ধতিতে এটি করা হয়েছে। যেমন Lists.newArrayList () যা আপনাকে লিখতে দেয়

List<String> names = Lists.newArrayList();

বা স্থির আমদানি সহ

import static com.google.common.collect.Lists.*;
...
List<String> names = newArrayList();
List<String> names = newArrayList("one", "two", "three");

পেয়ারাতে এর মতো আরও খুব শক্তিশালী বৈশিষ্ট্য রয়েছে এবং আমি <> জন্য বেশি ব্যবহারের কথা ভাবতে পারি না।

যদি তারা হীরা অপারেটর আচরণটি ডিফল্টরূপে চালিত করতে যায় তবে এটি আরও কার্যকর হত, অর্থাত, টাইপটি ভাবের বাম দিক থেকে অন্তর্ভুক্ত হয় বা বাম দিকের ধরণটি ডান দিক থেকে অন্তর্ভুক্ত করা হয়। পরেরটি স্কালায় যা ঘটে।


3

ডায়মন্ড অপারেটরটির জন্য বিন্দুটি হ'ল জেনেরিক প্রকারের ঘোষণা দেওয়ার সময় কোডের টাইপিং হ্রাস করা। রানটাইম যা-ই হোক না কেন এটির কোনও প্রভাব নেই।

যদি আপনি জাভা 5 এবং 6 তে নির্দিষ্ট করেন তবেই পার্থক্য

List<String> list = new ArrayList();

এটি আপনাকে নির্দিষ্ট @SuppressWarnings("unchecked")করতে হবে list(অন্যথায় আপনি একটি চেক না করা কাস্ট সতর্কতা পাবেন)। আমার বোধগম্য হীরা অপারেটর উন্নয়নকে আরও সহজ করার চেষ্টা করছে। জেনেরিকদের রানটাইম কার্যকর করতে কিছুই করার দরকার নেই।


এমনকি আপনার এ টিকাটি ব্যবহার করতে হবে না। কমপক্ষে একটিগ্রহে, আপনি কেবল এই সম্পর্কে আপনাকে সতর্ক না করার জন্য কম্পাইলারকে বলতে পারেন এবং আপনি ভাল আছেন ...
জেরুস

টীকাটি দেওয়া ভাল। প্রতিটি বিকাশকারীরা এখানে Elpipse ব্যবহার করে না।
বুহাকে সিন্ধি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.