জাভা এর + =, - =, * =, / = যৌগিক কার্যনির্বাহী অপারেটরদের কাস্টিংয়ের দরকার নেই কেন?


3633

আজ অবধি, আমি ভেবেছিলাম উদাহরণস্বরূপ:

i += j;

এর জন্য কেবল একটি শর্টকাট ছিল:

i = i + j;

তবে আমরা যদি এটি চেষ্টা করি:

int i = 5;
long j = 8;

তারপর i = i + j;সংকলন করবে না তবে i += j;জরিমানা সংকলন করবে।

এর অর্থ কি আসলে এই i += j;জাতীয় কোনও কিছুর শর্টকাট i = (type of i) (i + j)?


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

103
জাভাতে লেখা ফ্লাইট কন্ট্রোল সিস্টেমে, এটি আপনার উদ্বেগের মধ্যে সবচেয়ে কম হবে @ এসকিউএলডাইভার
রস

10
আসলে i+=(long)j;এমনকি জরিমানা সংকলন করবে।
থারিন্ডু সতীশচন্দ্র

6
নির্ভুলতার জন্য এক সেট বিকাশকারী দ্বারা এবং ধরণের সহজলভ্যতার জন্য ধ্রুবক চাপ দেওয়া সত্যিই আকর্ষণীয় interesting আমাদের প্রায় ভাষাটির দুটি সংস্করণ প্রয়োজন, একটি আশ্চর্যজনকভাবে নির্ভুল এবং একটি যা ব্যবহার করা সহজ। উভয় দিক থেকে জাভা ঠেলাঠেলি এটি উভয় দলের পক্ষে অনুপযুক্ত হওয়ার দিকে নিয়ে যায়।
বিল কে

5
যদি কাস্টিংয়ের প্রয়োজন হয় তবে আপনি এটি কোথায় রাখবেন? i += (int) f;সংযোজনের আগে চ কাস্ট করুন, সুতরাং এটি সমতুল্য নয়। (int) i += f;ফল নির্ধারিত হওয়ার পরে, সমতুল্য নয়। এমন কোনও কাস্ট স্থাপনের কোনও জায়গা নেই যা আপনাকে বোঝানোর পরে মানটি কাস্ট করতে চাইবে তা বোঝায়, তবে নিয়োগের আগে।
নরিল টেম্পেস্ট

উত্তর:


2441

এই প্রশ্নগুলির সাথে সর্বদা, জেএলএস উত্তর রাখে holds এই ক্ষেত্রে .215.26.2 যৌগিক বরাদ্দ অপারেটরগুলি । একটি নিষ্কাশন:

ফর্ম একটি যৌগ নিয়োগ অভিব্যক্তি E1 op= E2সমতূল্য E1 = (T)((E1) op (E2)), যেখানে Tপ্রকার E1, যে ব্যতীত E1শুধুমাত্র একবার মূল্যায়ন করা হয়।

Example15.26.2 থেকে উদ্ধৃত একটি উদাহরণ

[...] নিম্নলিখিত কোডটি সঠিক:

short x = 3;
x += 4.6;

এবং x এর মান having এর ফলাফল হিসাবে এটি সমান:

short x = 3;
x = (short)(x + 4.6);

অন্য কথায়, আপনার অনুমানটি সঠিক।


42
i+=jআমি নিজেকে যাচাই করলাম তাই সংকলন করেছিলাম, তবে এর ফলে সঠিকতা হারাতে পারে? যদি এটি হয় তবে এটি আই = আই + জেও কেন ঘটতে দেয় না? আমাদের এখানে বাগ কেন?
খারাপ_কিপয়েন্ট

46
@ অর্ণিয়াকা: আমি অনুমান করছি যে ভাষা ডিজাইনাররা অনুভব করেছিলেন যে এক ক্ষেত্রে ( i += j), যথার্থতা হারাতে অন্য ক্ষেত্রে ( i = i + j) এর বিপরীতে যথাযথ ক্ষতি হ্রাস করা উচিত বলে ধরে নেওয়া নিরাপদ
লুকাশ এদার

12
না, ঠিক আছে, আমার সামনে! দুঃখিত আমি এটি আগে খেয়াল করেনি। আপনার উত্তরের হিসাবে E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), সুতরাং এটি নিখুঁত ডাউন টাইপকাস্টিংয়ের মতো (দীর্ঘ থেকে আন্তঃ অবধি)। যেখানে আই = আই + জে, আমরা এটি স্পষ্টভাবে করতে হবে, অর্থাত, (T)অংশটি সরবরাহ করে E1 = ((E1) op (E2))না?
খারাপ_কিপয়েন্ট

11
জাভা সংকলক কেন টাইপকাস্ট যুক্ত করার সম্ভাব্য কারণ হ'ল যদি আপনি বেমানান ধরনেরগুলিতে গাণিতিক সম্পাদনা করার চেষ্টা করছেন তবে চুক্তিবদ্ধ ফর্মটি ব্যবহার করে ফলাফলের টাইপকাস্ট করার কোনও উপায় নেই। ফলাফলের একটি টাইপকাস্ট সমস্যাযুক্ত যুক্তির টাইপকাস্টের চেয়ে সাধারণত আরও সঠিক। বেমানান ধরনের ব্যবহার করার সময় কোনও টাইপকাস্ট সংকোচনের অকেজো হয়ে উঠবে না, কারণ এটি সর্বদা সংকলককে ত্রুটিটি ছুঁড়ে মারতে বাধ্য করে।
ThePyroEagle

6
এটি বৃত্তাকার নয়। এটি castালাই (= কেটে গেছে)
লুকাশ এদার

483

এই কাস্টিংয়ের একটি ভাল উদাহরণ হ'ল * = বা / = ব্যবহার করা

byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57

অথবা

byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40

অথবা

char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'

অথবা

char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'

11
@ অক্ষত আগরওয়াল সিএইচ একটি চর। 65 * 1.5 = 97.5 -> বুঝেছেন?
সজল দত্ত

79
হ্যাঁ, তবে আমি দেখতে পাচ্ছি এখানে কিছু শিক্ষানবিস এখানে আসছেন, এটি পড়ছেন এবং এই ভেবে চলে যাবেন যে আপনি যে কোনও চরিত্রকে আপার কেস থেকে ছোট কেয়ারে 1.5 দ্বারা গুন করে রূপান্তর করতে পারবেন।
দাউদ ইবনে করিম

103
@ ডেভিডওয়ালেস যে কোনও চরিত্র যতক্ষণ তা হ'ল A;)
পিটার ল্যারি

14
@ পিটারল্যাওরি এবং @ ডেভিডওয়ালেস আমি আপনার গোপনীয়তা প্রকাশ করব - ch += 32 = ডি
মিনহাস কামাল ১16'১16

256

খুব ভাল প্রশ্ন। জাভা ল্যাঙ্গুএজ স্পেসিফিকেশন আপনার পরামর্শের নিশ্চিত।

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি সঠিক:

short x = 3;
x += 4.6;

এবং x এর মান having এর ফলাফল হিসাবে এটি সমান:

short x = 3;
x = (short)(x + 4.6);

15
বা আরও মজা: "int x = 33333333; x + = 1.0f;"।
সুপারক্যাট

5
@ সুপের্যাট, এটি কোন কৌশল? একটি বিস্তৃত রূপান্তর যা ভুলভাবে গোল হয়, এর পরে একটি সংযোজন ঘটে যা ফলস্বরূপ ফল পরিবর্তন করে না, আবার এমন ফলাফল উত্পন্ন করতে পুনরায় অন্তর্ভুক্ত হয় যা সাধারণ মানুষের মনের জন্য সবচেয়ে অপ্রত্যাশিত।
নেক্সাস

1
@neXus: এই প্রোগ্রামটিতে, রূপান্তর নিয়ম চিকিত্সা করা উচিত ছিল double->floatপ্রসার যেমন, ভিত্তি যে ধরনের মান উপর floatটাইপ তুলনায় কম বিশেষভাবে বাস্তব সংখ্যার চিহ্নিত double। যদি doubleকোনও একটি সম্পূর্ণ ডাক ঠিকানা এবং float5-সংখ্যার পোস্টাল কোড হিসাবে দেখেন, একটি সম্পূর্ণ ঠিকানা দেওয়া একটি পোস্ট কোডের জন্য একটি অনুরোধ সন্তুষ্ট করা সম্ভব তবে কেবল একটি ডাক কোড দেওয়া একটি সম্পূর্ণ ঠিকানার জন্য অনুরোধটি সঠিকভাবে নির্দিষ্ট করা সম্ভব নয় । রাস্তার ঠিকানাটিকে একটি পোস্ট কোডে রূপান্তর করা একটি ক্ষতির কাজ, তবে ...
সুপারক্যাট

1
... যে ব্যক্তির একটি সম্পূর্ণ ঠিকানা প্রয়োজন তিনি সাধারণত একটি ডাক কোড চাইবেন না। রূপান্তরটি float->doubleমার্কিন ডাক কোড 90210 "মার্কিন ডাকঘর, বেভারলি হিলস সিএ 90210" দিয়ে রূপান্তর করার সমতুল্য।
সুপারক্যাট

181

হ্যাঁ,

মূলত যখন আমরা লিখি

i += l; 

সংকলক এটিকে রূপান্তর করে

i = (int)(i + l);

আমি সবেমাত্র .classফাইল কোডটি যাচাই করেছি ।

সত্যিই জানা ভাল জিনিস


3
আপনি কি আমাকে বলতে পারবেন এটি কোন শ্রেণিকোষ?
ন্যানোফারাড

6
@ হেক্সাফ্রাকশন: ক্লাস ফাইল বলতে কী বোঝ? আপনি যদি আমার পোস্টে উল্লিখিত ক্লাস ফাইলটি সম্পর্কে জিজ্ঞাসা করেন তবে এটি আপনার জাভা ক্লাসের সম্মতিযুক্ত সংস্করণ
উমেশ અવস্তি

3
ওহ, আপনি "ক্লাস ফাইল কোড" উল্লেখ করেছেন, যা আমাকে বিশ্বাস করেছিল যে একটি নির্দিষ্ট শ্রেণিবদ্ধ জড়িত ছিল। আপনি এখন কি বলতে চাইছেন তা আমি বুঝতে পেরেছি।
ন্যানোফারাড

@ বোগদান যে সঠিকভাবে ব্যবহৃত ফন্টগুলির ক্ষেত্রে সমস্যা হওয়া উচিত নয়। যে প্রোগ্রামার প্রোগ্রামিংয়ের জন্য ভুল ফন্ট বেছে নেয় তার কীভাবে এগিয়ে যাওয়া যায় সে সম্পর্কে স্পষ্টভাবে চিন্তা করা উচিত ...
glglgl

7
@glglgl আমি একমত নই যে এই ক্ষেত্রে পার্থক্য করার জন্য ফন্টের উপর নির্ভর করা উচিত ... তবে প্রত্যেককেই সবচেয়ে ভাল বলে মনে করে তা চয়ন করার স্বাধীনতা পেয়েছে।
বোগদান আলেকজান্দ্রু

92

আপনার কাছ থেকে নিক্ষেপ করার প্রয়োজন longথেকে int explicitlyক্ষেত্রে i = i + l তারপর, এটা কম্পাইল এবং সঠিক আউটপুট দিতে হবে। মত

i = i + (int)l;

অথবা

i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.

তবে +=এটির ক্ষেত্রে কেবল সূক্ষ্মভাবে কাজ করে কারণ অপারেটর স্পষ্টভাবে ডান ভেরিয়েবলের ধরণ থেকে বাম ভেরিয়েবলের প্রকারে টাইপ কাস্টিং করে তাই স্পষ্টভাবে কাস্ট করার প্রয়োজন নেই।


7
এই ক্ষেত্রে, "অন্তর্নিহিত কাস্ট" ক্ষতিগ্রস্থ হতে পারে। প্রকৃতপক্ষে, তার উত্তরে @LukasEder যুক্তরাষ্ট্রের মতো, এর ঢালাই intসঞ্চালিত হয় পরে+ । সংকলকটি (যদি?) একটি সতর্কতা ছুঁড়ে ফেলত তবে তা যদি সত্যিই কাস্ট করে longদেয় int
রোমেন

63

এখানে সমস্যা টাইপ কাস্টিং জড়িত।

আপনি যখন দীর্ঘ এবং দীর্ঘ যোগ করেন,

  1. ইন্ট অবজেক্ট দীর্ঘতে কাস্ট করা হয় এবং উভয়ই যুক্ত হয় এবং আপনি দীর্ঘ বস্তু পান।
  2. তবে লম্বা অবজেক্ট ইনটিকে স্পষ্টভাবে কাস্ট করা যায় না। সুতরাং, আপনি স্পষ্টভাবে এটি করতে হবে।

তবে +=এমনভাবে কোড করা হয় যাতে এটি টাইপ ingালাই করে না।i=(int)(i+m)


54

জাভা টাইপ রূপান্তরগুলি স্বয়ংক্রিয়ভাবে সঞ্চালিত হয় যখন একটি অ্যাসাইনমেন্ট অপারেশনের ডান হাতের এক্সপ্রেশনটির ধরণটি অ্যাসাইনমেন্টের বাম হাতের ভেরিয়েবলের ধরণে নিরাপদে প্রচার করা যেতে পারে। এইভাবে আমরা নিরাপদে নির্ধারণ করতে পারি:

 বাইট -> সংক্ষিপ্ত -> int -> দীর্ঘ -> ভাসা -> দ্বিগুণ। 

একইভাবে অন্য রাস্তায় কাজ করবে না। উদাহরণস্বরূপ, আমরা স্বয়ংক্রিয়ভাবে একটি দীর্ঘকে একটি int তে রূপান্তর করতে পারি না কারণ প্রথমটির জন্য দ্বিতীয়টির চেয়ে বেশি স্টোরেজ প্রয়োজন এবং ফলস্বরূপ তথ্য হারিয়ে যেতে পারে। এই ধরনের রূপান্তর জোর করতে আমাদের অবশ্যই একটি স্পষ্ট রূপান্তর পরিচালনা করতে হবে।
প্রকার - রূপান্তর


2
আরে তবে এর longচেয়ে 2 গুণ বড় float
প্রদর্শিত নাম

11
floatপ্রতিটি সম্ভাব্য intমান ধরে রাখতে পারে না এবং একটি doubleপ্রতিটি সম্ভাব্য longমান ধরে রাখতে পারে না ।
অ্যালেক্স MDC

2
"নিরাপদে রূপান্তরিত" বলতে কী বোঝ? উত্তরের উত্তর দিক থেকে আমি অনুমান করতে পারি যে আপনি বোঝাচ্ছেন স্বয়ংক্রিয় রূপান্তর (অন্তর্নিহিত কাস্ট) যা অবশ্যই ভাসমান -> দীর্ঘ ক্ষেত্রে সত্য নয়। ভাসমান পাই = 3.14f; দীর্ঘ বি = পাই; সংকলক ত্রুটি হতে হবে।
লুক

1
আপনি পূর্ণসংখ্যার আদিম ধরণের সাথে ভাসমান পয়েন্ট আদিম প্রকারের পার্থক্য করা ভাল better তারা একই জিনিস না।
ThePyroEagle

জাভাতে সরল রূপান্তর নিয়ম রয়েছে যার জন্য অনেকগুলি নিদর্শনগুলিতে কাস্ট ব্যবহার করা প্রয়োজন যেখানে বর্ণ ছাড়াই আচরণ অন্যথায় প্রত্যাশার সাথে মেলে তবে সাধারণত অনেকগুলি নিদর্শনগুলিতে ক্যাসেটের প্রয়োজন হয় না usually উদাহরণস্বরূপ, একটি সংকলক double d=33333333+1.0f;অভিযোগ ছাড়াই গ্রহণ করবে , যদিও ফলাফল 33333332.0 ফলাফল সম্ভবত উদ্দিষ্ট উদ্দেশ্যটি ছিল না (ঘটনাক্রমে, 33333334.0f এর গাণিতিকভাবে সঠিক উত্তরটি উভয়ই হিসাবে উপস্থাপনযোগ্য হবে ) floatবা int)
সুপারক্যাট

46

কখনও কখনও, একটি সাক্ষাত্কারে এ জাতীয় প্রশ্ন জিজ্ঞাসা করা যেতে পারে।

উদাহরণস্বরূপ, আপনি যখন লিখবেন:

int a = 2;
long b = 3;
a = a + b;

কোনও স্বয়ংক্রিয় টাইপকাস্টিং নেই। সি ++ তে উপরের কোডটি সংকলন করতে কোনও ত্রুটি হবে না, তবে জাভাতে আপনি এরকম কিছু পাবেন Incompatible type exception

সুতরাং এটি এড়াতে আপনার কোডটি অবশ্যই লিখতে হবে:

int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting

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

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

25

মূল পার্থক্যটি হ'ল a = a + b, এখানে কোনও টাইপকাস্টিং চলছে না, এবং তাই টাইপকাস্টিং না করার জন্য সংকলকটি আপনাকে রেগে যায়। তবে এর সাথে a += b, এটি সত্যি কী করছে তার bসাথে সামঞ্জস্যপূর্ণ টাইপের টাইপকাস্টিং a। সুতরাং আপনি যদি

int a=5;
long b=10;
a+=b;
System.out.println(a);

আপনি যা করছেন তা হ'ল:

int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);

5
যৌগিক অ্যাসাইনমেন্ট অপারেটরগুলি বাইনারি অপারেশনের ফলাফলের সংকীর্ণ রূপান্তর সম্পাদন করে, ডান হাতের অপারেন্ড নয়। সুতরাং আপনার উদাহরণে, 'a + = b' 'a = a + (int) b' এর সমতুল্য নয়, তবে এখানে অন্যান্য উত্তর দ্বারা ব্যাখ্যা করা হয়েছে 'a = (int) (a + b)' এর সাথে।
লিউ ব্লচ

13

সূক্ষ্ম বিন্দু এখানে ...

i+jকখন jডাবল হয় এবং কোনও অন্তর্নিহিত হয় তার জন্য এখানে অন্তর্নিহিত টাইপেকাস্ট থাকে i। জাভা সর্বদা একটি পূর্ণসংখ্যাকে ডাবল রূপান্তর করে যখন তাদের মধ্যে কোনও অপারেশন থাকে।

একটি পূর্ণসংখ্যা i+=jকোথায় iএবং jদ্বিগুণ হিসাবে স্পষ্ট করে তা বর্ণনা করা যায়

i = <int>(<double>i + j)

দেখুন: অন্তর্ভুক্ত castালাইয়ের এই বিবরণ

স্পষ্টতার জন্য আপনি এই ক্ষেত্রে টাইপকাস্ট jকরতে চাইতে পারেন (int)


1
আমি মনে করি আরও মজার একটি মামলা হতে পারে int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;। শূন্যে যোগ করা someIntএর মানকে প্রভাবিত করবে না, তবে প্রচার someIntকরা floatএর মান পরিবর্তন করতে পারে।
সুপারক্যাট

4

জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন এক ধরণের যেখানে সমান হতে সংজ্ঞা E1 op= E2দেয় এবং একবার মূল্যায়ন করা হয়E1 = (T) ((E1) op (E2))TE1E1

এটি একটি প্রযুক্তিগত উত্তর, তবে আপনি ভাবছেন যে কেন এটি একটি ঘটনা। ঠিক আছে, নীচের প্রোগ্রামটি বিবেচনা করা যাক।

public class PlusEquals {
    public static void main(String[] args) {
        byte a = 1;
        byte b = 2;
        a = a + b;
        System.out.println(a);
    }
}

এই প্রোগ্রামটি কী মুদ্রণ করে?

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

তবে যদি a = a + bএটি কাজ না করে, তার অর্থ হ'ল a += bএটি কখনই বাইটের জন্য কাজ করে না যদি এটি E1 += E2সংজ্ঞায়িত করা হয় E1 = E1 + E2। পূর্ববর্তী উদাহরণটি যেমন দেখায়, সত্যই এটি হবে। +=বাইটস এবং শর্টসগুলির জন্য অপারেটরকে কাজ করার জন্য একটি হ্যাক হিসাবে , সেখানে জড়িত অন্তর্নিহিত কাস্ট রয়েছে। এটি হ্যাকের মতো দুর্দান্ত নয়, তবে জাভা ০.০ কাজের সময়, ফোকাসটি ছিল ভাষাটি শুরু করার সাথে সাথেই শুরু করা। এখন, পিছনের সামঞ্জস্যের কারণে, জাভা 1.0 এ প্রবর্তিত এই হ্যাকটি সরানো যায়নি।

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