জাভাতে ভেরিয়েবল কাস্টিং


84

আমি ভাবছি যদি কেউ আমাকে বলতে পারে যে কাস্টিং কীভাবে কাজ করে? আমার কখন এটি করা উচিত তা আমি বুঝতে পারি, তবে আসলে এটি কীভাবে কাজ করে তা নয়। আদিম ডেটা ধরণের ক্ষেত্রে আমি আংশিকভাবে বুঝতে পারি তবে যখন ingালাইয়ের জিনিসগুলির কথা আসে তখন আমি বুঝতে পারি না এটি কীভাবে কাজ করে।

অবজেক্ট টাইপযুক্ত কোনও অবজেক্টকে কীভাবে হঠাৎ হঠাৎ কাস্ট করা যায়, আসুন বলি, MyType(কেবল উদাহরণ) এবং তারপরে সমস্ত পদ্ধতি পাওয়া যাবে?


প্রস্তাবিত পাঠ্য: উত্তরাধিকার
স্পঞ্জ

উত্তর:


182

জাভাতে কাস্টিং যাদু নয়, আপনি এটি সংকলককে বলছেন যে টাইপ এ এর ​​একটি অবজেক্ট আসলে আরও নির্দিষ্ট ধরণের বি এর, এবং এভাবে বি তে সমস্ত পদ্ধতিতে অ্যাক্সেস অর্জন করে যা আপনি অন্যথায় না করতেন। কাস্টিং সম্পাদন করার সময় আপনি কোনও ধরণের যাদু বা রূপান্তর করছেন না, আপনি মূলত সংকলককে বলছেন "বিশ্বাস করুন, আমি জানি আমি কি করছি এবং আমি আপনাকে গ্যারান্টি দিতে পারি যে এই লাইনে এই অবজেক্টটি আসলে একটি <castোকান কাস্ট" এখানে টাইপ করুন। " উদাহরণ স্বরূপ:

Object o = "str";
String str = (String)o;

উপরেরটি ঠিক আছে, যাদু নয় এবং সব ঠিক আছে। ও তে সংরক্ষিত থাকা বস্তুটি আসলে একটি স্ট্রিং, এবং সেইজন্য আমরা কোনও সমস্যা ছাড়াই একটি স্ট্রিংয়ে কাস্ট করতে পারি।

এটি ভুল হতে পারে দুটি উপায় আছে। প্রথমত, যদি আপনি সম্পূর্ণ ভিন্ন উত্তরাধিকারের শ্রেণিবিন্যাসে দুটি ধরণের মধ্যে কাস্ট করছেন তবে সংকলকটি জানতে পারবে আপনি বোকা হয়ে যাচ্ছেন এবং আপনাকে থামিয়েছেন:

String o = "str";
Integer str = (Integer)o; //Compilation fails here

দ্বিতীয়ত, যদি তারা একই শ্রেণিবিন্যাসে থাকে তবে এখনও অবৈধ কাস্ট হয় তবে ClassCastExceptionরানটাইমের সময় একটি নিক্ষিপ্ত হবে:

Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here

এর মূলত অর্থ এই যে আপনি সংকলকের বিশ্বাস লঙ্ঘন করেছেন। আপনি এটিকে বলেছেন যে আপনি গ্যারান্টি দিতে পারবেন যে কোনও জিনিসটি নির্দিষ্ট ধরণের।

আপনার castালাই কেন দরকার? ভাল, আপনার সাথে শুরু করার জন্য কেবলমাত্র আরও সাধারণ ধরণের থেকে আরও নির্দিষ্ট ধরণের দিকে যেতে হবে। উদাহরণস্বরূপ, Integerউত্তরাধিকার সূত্রে প্রাপ্ত Number, সুতরাং আপনি যদি কোনও Integerহিসাবে এটি সংরক্ষণ করতে চান Numberতবে এটি ঠিক আছে (যেহেতু সমস্ত সংখ্যার সংখ্যা হয়)) তবে, আপনি যদি অন্য পথে যেতে চান তবে আপনার একটি castালাই প্রয়োজন - সমস্ত সংখ্যাই পূর্ণসংখ্যার নয় (পাশাপাশি পূর্ণসংখ্যা হিসাবে আমরা আছে Double, Float, Byte, Long, ইত্যাদি) নেই এবং এমনকি যদি আপনার প্রকল্প বা JDK মাত্র এক উপশ্রেণী, কেউ সহজে আরেকটি তৈরি এবং যে বিতরণ পারেনি, সেহেতু আপনি কোন গ্যারান্টি করেছি এমনকি যদি আপনি মনে হয় এটা একটি একক, সুস্পষ্ট পছন্দ !

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


আপনার ব্যাখ্যার জন্য ধন্যবাদ. আমি যদি এই সঠিকটি বুঝতে পারি তবে সম্ভবত আমি তা করি না, আপনি যখন কোনও বস্তু নিক্ষেপ করেন তখন আপনি কেবল কম্পাইলারকে বলছেন যে আমি এই স্মৃতিশ্রেণীতে থাকা অবজেক্টটি কীভাবে এই পদ্ধতিগুলির প্রতিক্রিয়া জানাতে জানি ইত্যাদি ইত্যাদি, তাই আমাকে অস্বীকার করবেন না? এটা কি ঠিক?
ব্যবহারকারী 626912

4
@ ব্যবহারকারী 626912 ধরণের - যদিও মেমরি ঠিকানার দিক থেকে এটি সম্পর্কে ভাবেন না। আপনি কেবল কম্পাইলারকে বলছেন না যে প্রদত্ত অবজেক্টটি একটি ইন্টারফেসের সাথে সঙ্গতিপূর্ণ এবং তাই প্রদত্ত পদ্ধতিগুলির বাস্তবায়ন রয়েছে (আপনি একই পদ্ধতিতে সম্পূর্ণ ভিন্ন বস্তু তৈরি করতে পারেন এবং castালাই প্রয়োজনীয়ভাবে কাজ করবে না)) আপনি সংকলকটি বলছেন যে এক প্রকারের বস্তুটি আসলে আরও নির্দিষ্ট ধরণের এবং তাই আপনি আরও নির্দিষ্ট নির্দিষ্ট অবজেক্টের জন্য উপলব্ধ পদ্ধতিগুলি ব্যবহার করতে পারেন। পলিমারফিজমটি পড়ুন যদি আপনি ইতিমধ্যে না থাকেন তবে এটি কিছু জিনিসকে আরও পরিষ্কার করে তুলতে সহায়তা করতে পারে।
মাইকেল বেরি

আমি আপনার বক্তব্যটিকে সন্দেহ করি "একটি সাধারণ ধরণের থেকে আরও নির্দিষ্ট ধরণের দিকে যাওয়ার সময় আপনার কেবল এটির দরকার হয়"। ((অবজেক্ট) gpsLastLoc.getLatitude ())। GetClass ()। GetSimpleName () রানটাইমে "ডাবল" নামটি ফিরিয়ে দেবে, এবং এটি আরও নির্দিষ্ট ধরণের থেকে আরও সাধারণ ধরণের ক্ষেত্রে ingালাইয়ের উদাহরণ।
ফল

4
@ 林果 皞 আপনি কেবল কোনও আদিমকে প্রচার করার জন্য এই ক্ষেত্রে কাস্টিং ব্যবহার করছেন - এটি আরও সাধারণ ধরণে যাওয়ার মতো নয় এবং জিনিসগুলি করার একটি খুব অদ্ভুত উপায়। আরও স্বাভাবিক (আরও ভাল) উপায় হবে Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()। উভয় ক্ষেত্রেই, আপনার কখনই প্রগতিশীল শ্রেণীর গতিবেগ নেওয়ার প্রয়োজন হবে না, যেহেতু যদি getLatitude()দ্বিগুণ আদিম ফেরত দেয়, আপনি সর্বদা জানেন যে এটি কোনও Doubleবস্তুতে উন্নীত হতে চলেছে ।
মাইকেল বেরি

আপনি যেভাবে রেখেছেন তা আমি পছন্দ করি, কোডটি "সংকলকের বিশ্বাসকে লঙ্ঘন করেছে"। (গীত। আপনার টাইপো আছে, আপনি "আপনি" এর পরিবর্তে "আপনি" লিখেছেন))
জেসন এল।

7

আসলে, ingালাই সবসময় কাজ করে না। যদি অবজেক্টটি কোনও instanceofশ্রেণি না হয় তবে আপনি এটিকে নিক্ষেপ করছেন আপনি ClassCastExceptionরানটাইমের সময় পাবেন।


5

ধরুন আপনি একটি নিক্ষেপ করতে চেয়েছিলেন Stringএকটি থেকে File(যে কোন অর্থে হ্যাঁ এটা দেখা যায় না), আপনি এটা সরাসরি কারণ নিক্ষেপ করতে পারবে না Fileবর্গ একটি শিশু এবং একটি পিতা বা মাতা না নয় Stringবর্গ (এবং কম্পাইলার অভিযোগ)।

তবে আপনি এতে কাস্ট করতে Stringপারেন Object, কারণ Stringএ একজন Object( Objectপিতামাতা)। তারপরে আপনি এই বস্তুকে একটিতে কাস্ট করতে পারেন File, কারণ ফাইলটি একটি Object

সুতরাং আপনার সমস্ত অপারেশনগুলি সংকলন সময়ে টাইপিং দৃষ্টিকোণ থেকে 'আইনী', তবে এর অর্থ এটি নয় যে এটি রানটাইমে কার্যকর হবে!

File f = (File)(Object) "Stupid cast";

সংকলকটি এটির অর্থ না দেয় এমনকি এটির অনুমতি দেবে তবে এটি ব্যতিক্রম সহ রানটাইম এ ক্রাশ হবে:

Exception in thread "main" java.lang.ClassCastException:
    java.lang.String cannot be cast to java.io.File

3

রেফারেন্স Castালাই কেবল তখনই কাজ করবে যদি এটি instanceofধরণের হয়। আপনি এলোমেলো রেফারেন্স কাস্ট করতে পারবেন না। এছাড়াও, আপনার আরও পড়তে হবে Casting Objects

যেমন

String string = "String";

Object object = string; // Perfectly fine since String is an Object

String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.

3

সঠিক উপায় এটি:

Integer i = Integer.class.cast(obj);

cast()সংকলন-সময় ingালাইয়ের জন্য পদ্ধতিটি অনেক বেশি নিরাপদ।

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