জাভা কাস্টিং ওভারহেড পরিচয় করিয়ে দেয়? কেন?


103

যখন আমরা এক ধরণের অবজেক্টগুলিকে অন্যটিতে কাস্ট করি তখন কি কোনও ওভারহেড থাকে? বা সংকলক কেবল সবকিছু সমাধান করে এবং রান টাইমে কোনও খরচ হয় না?

এটি কি সাধারণ জিনিস, না বিভিন্ন মামলা রয়েছে?

উদাহরণস্বরূপ, ধরুন আমাদের কাছে অবজেক্টের একটি অ্যারে [] রয়েছে, যেখানে প্রতিটি উপাদানের আলাদা আলাদা ধরন থাকতে পারে। তবে আমরা সর্বদা নিশ্চিতভাবে জানি যে, বলুন যে এলিমেন্ট 0 একটি ডাবল, উপাদান 1 স্ট্রিং। (আমি জানি এটি একটি ভুল নকশা, তবে আসুন কেবল ধরে নেওয়া যাক আমাকে এই কাজটি করতে হয়েছিল))

জাভা টাইপ তথ্য এখনও রান সময় কাছাকাছি রাখা? বা সংকলনের পরে সবকিছু ভুলে গেছে, এবং আমরা যদি (ডাবল) উপাদানগুলি [0] করি, আমরা কেবলমাত্র পয়েন্টারটি অনুসরণ করব এবং সেই 8 বাইটকে ডাবল হিসাবে ব্যাখ্যা করব, যা কিছু হোক না কেন?

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


উদাহরণস্বরূপ এবং ingালাইয়ের অভিনয়টি বেশ ভাল। : আমি এখানে সমস্যা বিভিন্ন পন্থা প্রায় Java7 মধ্যে কিছু সময়জ্ঞান পোস্ট stackoverflow.com/questions/16320014/...
Wheezil

এর ফলে অন্য প্রশ্ন খুব ভাল উত্তর আছে stackoverflow.com/questions/16741323/...
user454322

উত্তর:


77

2 ধরণের কাস্টিং রয়েছে:

অন্তর্নিহিত ingালাই , যখন আপনি কোনও প্রকার থেকে বিস্তৃত প্রকারে কাস্ট করেন, যা স্বয়ংক্রিয়ভাবে হয়ে যায় এবং কোনও ওভারহেড নেই:

String s = "Cast";
Object o = s; // implicit casting

সুস্পষ্ট কাস্টিং, যখন আপনি আরও বিস্তৃত থেকে আরও সংকীর্ণ হয়ে যান। এই ক্ষেত্রে, আপনাকে অবশ্যই স্পষ্টভাবে এর মতো castালাই ব্যবহার করতে হবে:

Object o = someObject;
String s = (String) o; // explicit casting

এই দ্বিতীয় ক্ষেত্রে, রানটাইমের ক্ষেত্রে ওভারহেড রয়েছে, কারণ দুটি প্রকারটি অবশ্যই পরীক্ষা করা উচিত এবং যদি কাস্টিং সম্ভব না হয় তবে জেভিএমকে অবশ্যই একটি ক্লাসকাস্টএক্সসেপশন নিক্ষেপ করতে হবে।

জাভা ওয়ার্ল্ড থেকে নেওয়া : ingালাইয়ের ব্যয়

কাস্টিং প্রকারের মধ্যে রূপান্তর করতে ব্যবহৃত হয় - বিশেষত রেফারেন্স ধরণের মধ্যে, আমাদের এখানে আগ্রহী কাস্টিং অপারেশনের জন্য।

আপকাস্ট অপারেশনগুলি (জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশনে প্রসারিত রূপান্তরগুলিও বলা হয়) একটি পূর্ব-শ্রেণীর রেফারেন্সে একটি সাবক্লাস রেফারেন্সকে রূপান্তর করে। এই ingালাই অপারেশনটি সাধারণত স্বয়ংক্রিয় হয়, যেহেতু এটি সর্বদা নিরাপদ এবং সংকলক দ্বারা সরাসরি প্রয়োগ করা যেতে পারে।

ডাউনকাস্ট অপারেশনগুলি (জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশনে সংকীর্ণ রূপান্তরগুলিও বলা হয়) একটি পূর্বক শ্রেণীর রেফারেন্সকে একটি সাবক্লাস রেফারেন্সে রূপান্তর করে। এই ingালাই ক্রিয়াকলাপটি এক্সিকিউশন ওভারহেড তৈরি করে, যেহেতু জাভা দরকার হয় তা নিশ্চিত করার জন্য রানটাইমটিতে কাস্ট করা উচিত। যদি রেফারেন্স করা অবজেক্টটি কাস্টের জন্য টার্গেট টাইপ বা or প্রকারের একটি সাবক্লাসের উদাহরণ না হয়, তবে চেষ্টা করা কাস্টের অনুমতি দেওয়া হয়নি এবং অবশ্যই একটি জাভা.লং.ক্লাসকাস্টএক্সসেপশন নিক্ষেপ করতে হবে।


100
সেই জাভাওয়ার্ল্ড নিবন্ধটি 10+ বছর পুরানো, সুতরাং আমি আপনার সেরা লবণের খুব বড় শস্য দিয়ে পারফরম্যান্সের বিষয়ে যে কোনও বিবৃতি দিয়ে থাকি।
skaffman

@ স্কাফম্যান, আসলে আমি লবণের দানা দিয়ে (যেভাবেই হোক না কেন পারফরম্যান্স সম্পর্কিত) কোনও বক্তব্য নেব।
পেসারিয়ার

আমি কি রেজিস্ট্রিটে কাস্ট করা অবজেক্টটি অর্পণ না করে এবং এটিতে কেবল কল করার পদ্ধতিটি ব্যবহার করব? পছন্দ((String)o).someMethodOfCastedClass()
পার্থ বিশ্বজিৎ

2
এখন নিবন্ধটি প্রায় 20 বছরের পুরানো। এবং উত্তরগুলিও বহু বছরের পুরনো। এই প্রশ্নের একটি আধুনিক উত্তর প্রয়োজন।
রাসলাভ

আদিম ধরণের সম্পর্কে কীভাবে? আমার অর্থ, উদাহরণস্বরূপ - সংক্ষিপ্ত থেকে সংক্ষিপ্ত কারণে অনুরূপ ওভারহেডে কাস্টিং?
luke1985

44

জাভা যুক্তিসঙ্গত বাস্তবায়নের জন্য:

প্রতিটি বস্তুর একটি হেডার থাকে, যা অন্যান্য জিনিসের মধ্যে থাকে, রানটাইম টাইপের পয়েন্টার (উদাহরণস্বরূপ Doubleবা String, তবে এটি কখনই CharSequenceবা হতে পারে না AbstractList)। রানটাইম সংকলক (সূর্যের ক্ষেত্রে সাধারণত হটস্পট) ধরে নিলে জেনেটেড মেশিন কোড দ্বারা কিছু পরীক্ষা করা দরকার তা স্থিরভাবে নির্ধারণ করতে পারে না।

প্রথমে রানটাইম টাইপের নির্দেশকটি পড়তে হবে be যাইহোক যাইহোক একই পরিস্থিতিতে ভার্চুয়াল পদ্ধতিতে কল করার জন্য এটি প্রয়োজনীয়।

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

তারপরে পঠিত মানটি কেবল expectedালাইয়ের প্রত্যাশিত স্ট্যাটিক ধরণের সাথে তুলনা করা দরকার। নির্দেশ সেট আর্কিটেকচারের উপর নির্ভর করে, অন্য নির্দেশের একটি ভুল শাখায় শাখা (বা ত্রুটি) করা দরকার। 32-বিট এআরএম এর মতো আইএসএর শর্তসাপেক্ষ নির্দেশনা রয়েছে এবং দুঃখের পথটি সুখী পথ দিয়ে যেতে সক্ষম হতে পারে।

ইন্টারফেসের একাধিক উত্তরাধিকারের কারণে ইন্টারফেসগুলি আরও কঠিন। সাধারণত ইন্টারফেসে শেষ দুটি ক্যাসটি রানটাইম টাইপে ক্যাশে থাকে। খুব প্রাথমিক দিনগুলিতে (এক দশক আগে) ইন্টারফেসগুলি কিছুটা ধীর ছিল, তবে এটি আর প্রাসঙ্গিক নয়।

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


1
আকর্ষণীয় - সুতরাং এর অর্থ এই নয় যে আমি অ-ইন্টারফেস ক্লাসগুলির জন্য লিখি যদি আমি সুপারক্লাস sc = (সুপারক্লাস) সাবক্লাস লিখি; যে (জিট অর্থাৎ লোড টাইম) সংকলক তাদের "ক্লাস" শিরোলেখগুলিতে প্রতিটি সুপারক্লাস এবং সাবক্লাসের অবজেক্ট থেকে অফসেটটিতে "স্থিরভাবে" স্থাপন করবে এবং তারপরে একটি সাধারণ অ্যাডের মাধ্যমে তুলনা করে বিষয়গুলি সমাধান করতে সক্ষম হবে? - এটি দুর্দান্ত এবং দ্রুত :) ইন্টারফেসের জন্য আমি কোনও ছোট হ্যাশটেবল বা বিট্রি এর চেয়ে খারাপ কিছু মনে করব না?
পিটার্ক

@ পেটারক ক্লাসের মধ্যে castালাইয়ের জন্য, উভয় অবজেক্টের ঠিকানা এবং "ভিটিবিএল" (পদ্ধতি পয়েন্টারগুলির সারণী, বর্গ শ্রেণিবদ্ধের টেবিল, ইন্টারফেস ক্যাশে, ইত্যাদি) পরিবর্তন করবেন না। সুতরাং [শ্রেনী] কাস্টটি প্রকারটি পরীক্ষা করে এবং যদি এটি ফিট করে তবে অন্য কিছু হওয়ার দরকার নেই।
টম হাটিন -

8

উদাহরণস্বরূপ, ধরুন আমাদের কাছে অবজেক্টের একটি অ্যারে [] রয়েছে, যেখানে প্রতিটি উপাদানের আলাদা আলাদা ধরন থাকতে পারে। তবে আমরা সর্বদা নিশ্চিতভাবে জানি যে, বলুন যে এলিমেন্ট 0 একটি ডাবল, উপাদান 1 স্ট্রিং। (আমি জানি এটি একটি ভুল নকশা, তবে আসুন কেবল ধরে নেওয়া যাক আমাকে এই কাজটি করতে হয়েছিল))

সংকলক একটি অ্যারের পৃথক উপাদানের প্রকারগুলি নোট করে না। এটি কেবল যাচাই করে যে প্রতিটি উপাদান প্রকাশের ধরণ অ্যারের উপাদান টাইপের জন্য নির্ধারিত হয়।

জাভা টাইপ তথ্য এখনও রান সময় কাছাকাছি রাখা? বা সংকলনের পরে সবকিছু ভুলে গেছে, এবং আমরা যদি (ডাবল) উপাদানগুলি [0] করি, আমরা কেবলমাত্র পয়েন্টারটি অনুসরণ করব এবং সেই 8 বাইটকে ডাবল হিসাবে ব্যাখ্যা করব, যা কিছু হোক না কেন?

কিছু তথ্য রান সময়ে চারপাশে রাখা হয়, কিন্তু পৃথক উপাদানগুলির স্থির ধরণের নয়। ক্লাস ফাইলের ফর্ম্যাটটি দেখে আপনি এটি বলতে পারেন।

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

তদ্ব্যতীত, লোকদের যেভাবে যাইহোক অ্যাপ্লিকেশন কোডটি লেখা উচিত নয়।


1
আদিমদের সম্পর্কে কী? (float) Math.toDegrees(theta)এখানেও কি কোনও উল্লেখযোগ্য ওভারহেড থাকবে?
এসডি

2
কিছু আদিম বর্ণের জন্য একটি ওভারহেড রয়েছে। এটি উল্লেখযোগ্য কিনা তা প্রসঙ্গে নির্ভর করে।
স্টিফেন সি

6

রানটাইম কাস্টিং সম্পাদনের জন্য বাইট কোড নির্দেশকে বলা হয় checkcastjavapকী নির্দেশাবলী উত্পন্ন হয় তা দেখতে আপনি জাভা কোডটি বিচ্ছিন্ন করতে পারেন।

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

class Point { int x, y; }
class ColoredPoint extends Point { int color; }
class Test {
    public static void main(String[] args) {
        ColoredPoint[] cpa = new ColoredPoint[10];
        Point[] pa = cpa;
        System.out.println(pa[1] == null);
        try {
            pa[0] = new Point();
        } catch (ArrayStoreException e) {
            System.out.println(e);
        }
    }
}

Point[] pa = cpaবৈধ যেহেতু ColoredPointপয়েন্টের একটি সাবক্লাস, তবে pa[0] = new Point()বৈধ নয়।

এটি জেনেরিক প্রকারের বিরোধী, যেখানে রানটাইমের সময় কোনও ধরণের তথ্য নেই। সংকলক checkcastযেখানে প্রয়োজন সন্নিবেশ নির্দেশাবলী।

জেনেরিক ধরন এবং অ্যারে টাইপ করার ক্ষেত্রে এই পার্থক্যটি অ্যারে এবং জেনেরিক ধরণের মিশ্রণ প্রায়শই অনুপযুক্ত করে তোলে।


2

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

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

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