জাভাতে "এই" কি কখনও শূন্য হতে পারে?


109

এই রেখাটি একটি শ্রেণিবদ্ধ পদ্ধতিতে দেখেছি এবং আমার প্রথম প্রতিক্রিয়াটি হ'ল বিকাশকারী এটি লিখেছিল তা উপহাস করা .. তবে তারপরে, আমি অনুভব করেছি যে আমি ঠিক আছি কিনা তা নিশ্চিত করা উচিত।

public void dataViewActivated(DataViewEvent e) {
    if (this != null)
        // Do some work
}

সেই লাইনটি কি কখনও মিথ্যা বলে মূল্যায়ন করবে?


104
সর্বদা প্রথমে উপহাস করুন এবং পরে প্রশ্ন করুন। গন্ধযুক্ত পাথরে কাউকে ছিঁড়ে ফেলার সুবর্ণ সুযোগ পুনরুদ্ধারের চেয়ে ক্ষমা চাওয়া সহজ।
জোয়েল ইথারটন

5
"গন্ধক বিড়ম্বনা" শব্দটির জন্য +1।
মার্টি পিট

13
আপনি কি মজার জানেন? সংকলক বাগের কারণে এটি সি # তে ঘটতে পারে!
অন্ধ 18

1
@ ব্লিডি কোড নমুনার জন্য +1 দেবে।
নাথান ফেজার

6
ভাল সি # এ এটি বাতিল হতে পারে। কিছু প্রান্ত ক্ষেত্রে। আমার একই প্রবণতা ছিল: স্তন্যপায়ীকে উপহাস করা তবে আমি কেবল শান্ত হয়ে গেলাম। : এখানে একটি চেহারা আছে stackoverflow.com/questions/2464097/...
আন্দ্রেই Rînea

উত্তর:


88

না এটা পারে না। আপনি যদি ব্যবহার করছেন this, তবে আপনি উদাহরণটিতে thisরয়েছেন তাই নকল নয়।

জেএলএস বলে:

প্রাথমিক অভিব্যক্তি হিসাবে ব্যবহৃত হওয়ার সময়, কীওয়ার্ডটি এমন কোনও মানকে নির্দেশ করে যা সেই অবজেক্টের জন্য একটি রেফারেন্স যার জন্য উদাহরণ পদ্ধতিটি চাওয়া হয়েছিল (§15.12), বা অবজেক্টটি নির্মিত হচ্ছে।

আপনি যদি কোনও বস্তু থেকে কোনও পদ্ধতিতে অনুরোধ করেন তবে অবজেক্টটি বিদ্যমান বা আপনার একটি NullPointerExceptionআগে থাকতে পারে (বা এটি একটি স্ট্যাটিক পদ্ধতি তবে তারপরে thisআপনি এটি ব্যবহার করতে পারবেন না )।


সংস্থানসমূহ:


4
আমি জাভা সম্পর্কে গভীরভাবে জানি না, তবে সি ++ এ thisএকটি উদাহরণ পদ্ধতির NULL হতে পারে। সুতরাং আমি পুরোপুরি নিশ্চিত নই যে এটি জাভায় যথেষ্ট কারণ।
কেনেটিএম

4
এমন কিছুতে নাল পয়েন্টার ব্যতিক্রম foo.bar()ছুঁড়ে ফেলা হবে যখন fooএটি আবিষ্কার করা হবে null। পদ্ধতিতে প্রবেশের আগে এটি ঘটে, তবে আসল গল্পটি হল কল করার চেষ্টা করার কোনও পদ্ধতি নেই।
ক্লদিউ

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

5
@ কেনি: অপরিজ্ঞাত আচরণ ছাড়াই নয় , যদিও আপনি যদি আপনার প্রয়োগের বিশদটি জানেন তবে আপনি এটি ব্যবহার করতে পারেন।

4
আমি এই নির্দিষ্ট উত্তরটি সাবস্ক্রাইব করব না, এমনকি যদি এটি সম্পূর্ণ জ্ঞান করে। আমার কাছে একটি অ্যান্ড্রয়েড অ্যাপের জন্য ক্র্যাশ প্রতিবেদন রয়েছে যেখানে ভ্যারিয়েবলের অন্য থ্রেড থেকে নাল-আইফিড হওয়ার পরে যখন কোনও উদাহরণ পদ্ধতি ডাকা হয় তখন এই == নাল হয়। আসল কলটি ভেরিয়েবলটি শূন্য হওয়া সত্ত্বেও চলে যায় এবং যখন এটি কোনও সদস্য সদস্য পড়ার চেষ্টা করে তখন তা ক্র্যাশ হয়ে যায় :)
অ্যাড্রিয়ান ক্রিয়েউ

63

এটি নিজেকে জিজ্ঞাসার মতো "আমি কি বেঁচে আছি?" thisকখনই নਾਲ হতে পারে না


44
আমি কি বেঁচে আছি ?! ও god
শ্বর

আপনি এটিকে স্বচ্ছোক্ত বলে মনে করছেন this != null। এটি নয় - সি ++ এ, উদাহরণস্বরূপ, অ-ভার্চুয়াল পদ্ধতির জন্য thisভাল হতে পারে NULL
নিকি

1
@ নিকি কিছু দিক থেকে এটি স্ব-স্পষ্ট। এমনকি সি ++ তেও, যে কোনও প্রোগ্রামেই এটি ঘটে সেটির আচরণের সংজ্ঞা নেই। এটি জিসিসিতে ভার্চুয়াল ফাংশনগুলির জন্যও ঘটতে পারে: আদর্শ one.com/W7RmU
জোহানেস স্কাউব -

8
@ জন: আপনি আছেন নির্যাতনের অংশ আপনি এটি নিশ্চিত করতে পারবেন না।

@ জোহানেস শ্যাব-লিটব এটি সত্য নয় যে এর জন্য নাল রেফার সাথে সি ++ প্রোগ্রামের আচরণ অপরিবর্তিত। এটির সংজ্ঞা দেওয়া আছে যতক্ষণ আপনি এটিকে
অবজ্ঞা

9

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

এবং আরও আকর্ষণীয়ভাবে এটি সেট করার চেষ্টা করুন:

this = null;

চিন্তা করুন? এটি কীভাবে সম্ভব, আপনি যে শাখায় বসে আছেন তা কাটার মতো হবে না। যেহেতু 'এটি' কীওয়ার্ড ক্লাসের আওতায় পাওয়া যায় সুতরাং আপনি এটি বলার সাথে সাথে = নাল; ক্লাসের মধ্যে কোথাও আপনি তখন মূলত জেভিএমকে কিছু অপারেশনের মাঝামাঝি সেই অবজেক্টকে অর্পণ করা মেমরিটি মুক্ত করতে বলছেন যা জেভিএম কেবল ঘটতে দিতে পারে না কারণ এটি অপারেশন শেষ করে নিরাপদে ফিরে আসতে হবে।

তদুপরি, চেষ্টা করার this = null;ফলে সংকলক ত্রুটি হবে। কারণটি খুব সহজ, জাভাতে (বা যে কোনও ভাষা) একটি কীওয়ার্ডকে কখনই একটি মান নির্ধারণ করা যায় না, কোনও কীওয়ার্ড কখনই কোনও অ্যাসাইনমেন্ট অপারেশনের বাম মান হতে পারে না।

অন্যান্য উদাহরণ, আপনি বলতে পারবেন না:

true = new Boolean(true);
true = false;

ভাল ব্যাখ্যা বন্ধু।
পঙ্কজ শর্মা

@ পঙ্কজশর্মা ধন্যবাদ :)
12:59

আমি এটি খুঁজে পেয়েছি কারণ আমি ব্যবহার করতে পারি কিনা তা দেখতে চেয়েছিলাম this = null। আমার উদাহরণটি অ্যান্ড্রয়েডে ছিল যেখানে আমি একটি ভিউ অপসারণ করতে এবং ভিউটি পরিচালনা করে এমন অবজেক্টটি বাতিল করতে চাইতাম। তারপরে আমি এমন একটি পদ্ধতি ব্যবহার করতে চেয়েছিলাম remove()যা প্রকৃত দৃষ্টিভঙ্গি মুছে ফেলবে এবং তারপরে হ্যান্ডলার-অবজেক্টটি অকেজো হয়ে উঠবে, তাই আমি এটিকে বাতিল করতে চেয়েছিলাম।
ইয়োকিচ

নিশ্চিত না যে আমি আপনার দাবির সাথে একমত (কমপক্ষে মাঝের অংশটি; লভ্যালু অংশটি ঠিক আছে ... যদিও আমি নিশ্চিত যে সত্যিকার অর্থে ভাঙা ভাষাগুলি রয়েছে যা আপনাকে যথাযথ = মিথ্যা নির্ধারণ করতে দেয় এবং এমনকি যে ভাষাগুলি আমি ভাঙ্গা বলি না সেগুলিও এটির অনুমতি দেয়) প্রতিবিম্ব বা অনুরূপ কৌশল))। যাইহোক, যদি আমার কিছু অবজেক্ট থাকে এবং আমি করতাম (এটি অবৈধ উপেক্ষা করে) foo.this = নাল, foo এখনও স্মৃতিতে নির্দেশ করবে এবং তাই জেভিএম আবর্জনা সংগ্রহ করবে না।
ফোনে

@ প্রথমত প্রশ্নটি জাভা ভাষা সম্পর্কে স্পষ্টভাবে কথা বলেছে, তদুপরি, আমি এমন কোনও ভাষাতে আসিনি যেখানে এই = নালটি সেট করার অনুমতি রয়েছে। এটি হ'ল যদি এ জাতীয় ভাষা বিদ্যমান থাকে তবে আমি অত্যন্ত সন্দেহ করি যে এই জাতীয় ভাষায় 'এটি'র একই প্রসঙ্গ এবং আদর্শ থাকবে।
ডিসি

7

আপনি যদি এর সাথে -target 1.3বা তার আগে সংকলন করেন তবে একটি বহিরাগত this হতে পারে null। বা কমপক্ষে এটি অভ্যস্ত ...


2
আমি প্রতিবিম্বের মাধ্যমে অনুমান করি যে আমরা বাইরেরটিকে শূন্য করতে পারি। তিনি রেফারেন্সিংয়ে নাল পয়েন্টার ব্যতিক্রম Outer.this.member
পেলে

3

কোন শ্রেণীর উদাহরণের কোনও পদ্ধতিতে কল করতে উদাহরণটি উপস্থিত থাকতে হবে। উদাহরণটি স্পষ্টভাবে পদ্ধতিটির পরামিতি হিসাবে প্রেরণ করা হয়েছে, দ্বারা রেফারেন্স করা হয়েছে this। যদি thisহয় nullতবে এর পদ্ধতি কল করার কোনও উদাহরণ ছিল না।


3

এটি যথেষ্ট নয় যে ভাষা এটি প্রয়োগ করে। ভিএম এটি প্রয়োগ করা প্রয়োজন। ভিএম এটি প্রয়োগ না করে আপনি একটি সংকলক লিখতে পারেন যা জাভাতে লিখিত পদ্ধতিতে কল করার আগে নাল চেকটি প্রয়োগ করে না। একটি উদাহরণ পদ্ধতি অনুরোধের জন্য ওপকোডগুলির মধ্যে এই রেফটি স্ট্যাকের উপরে লোড করা অন্তর্ভুক্ত দেখুন: http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787 । একটি নাল রেফার জন্য এটি প্রতিস্থাপন সত্যই পরীক্ষা মিথ্যা হবে


3

স্ট্যাটিক ক্লাস পদ্ধতিগুলিতে, thisসংজ্ঞায়িত হয় না যেহেতু thisউদাহরণগুলির সাথে সম্পর্কিত এবং ক্লাস নয়। আমার বিশ্বাস এটি thisস্থিতিক প্রসঙ্গে কীওয়ার্ডটি ব্যবহারের চেষ্টা করতে একটি সংকলক ত্রুটি দেবে ।


2

একটি সাধারণ thisকখনই nullআসল জাভা কোড 1 এ থাকতে পারে না এবং আপনার উদাহরণটি একটি সাধারণ ব্যবহার করে this। আরও তথ্যের জন্য অন্যান্য উত্তরগুলি দেখুন।

যোগ্য কখনও হওয়া this উচিত নয় null, তবে এটি এড়ানো সম্ভব। নিম্নোক্ত বিবেচনা কর:

public class Outer {
   public Outer() {}

   public class Inner {
       public Inner() {}

       public String toString() {
           return "outer is " + Outer.this;  // Qualified this!!
       }
   }
}

যখন আমরা একটি উদাহরণ তৈরি করতে চাই Inner, আমাদের এটি করা দরকার:

public static void main(String[] args) {
    Outer outer = new Outer();
    Inner inner = outer.new Inner();
    System.out.println(inner);

    outer = null;
    inner = outer.new Inner();  // FAIL ... throws an NPE
}

আউটপুটটি হ'ল:

outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
        at Outer.main(Outer.java:19)

এটি দেখানো হচ্ছে যে এটির Innerএকটি nullরেফারেন্স সহ আমাদের তৈরির প্রচেষ্টা Outerব্যর্থ হয়েছে।

আসলে, আপনি যদি "বিশুদ্ধ জাভা" খামের মধ্যে থাকেন তবে আপনি এটি ভাঙ্গতে পারবেন না।

যাইহোক, প্রতিটি Innerউদাহরণের মধ্যে একটি লুকানো finalসিন্থেটিক ক্ষেত্র (ডাকা "this$0") থাকে যা এতে রেফারেন্স ধারণ করে Outer। আপনি যদি সত্যই কৌতূহলী nullহন তবে ক্ষেত্রটি নির্ধারণের জন্য "অ-খাঁটি" অর্থ ব্যবহার করা সম্ভব ।

  • আপনি এটি করতে ব্যবহার Unsafeকরতে পারেন।
  • আপনি এটি করতে স্থানীয় কোড ব্যবহার করতে পারেন (যেমন জেএনআই)।
  • আপনি এটি প্রতিবিম্ব ব্যবহার করে করতে পারেন।

যেভাবেই আপনি এটি করেন, শেষ ফলাফলটি হ'ল Outer.thisএক্সপ্রেশনটি null2 এ মূল্যায়ন করবে ।

সংক্ষেপে, এটা সম্ভব একজন যোগ্যতাসম্পন্ন জন্য thisহতে null। তবে যদি আপনার প্রোগ্রামটি "খাঁটি জাভা" বিধি অনুসরণ করে তবে এটি অসম্ভব


1 - আমি হাতের মাধ্যমে বাইটকোডগুলি "লেখা" এবং সত্যিকারের জাভা হিসাবে ছাড়িয়ে দেওয়া, বিসিইএল বা অনুরূপ ব্যবহার করে বাইটকোডগুলি টুইট করা বা স্থানীয় কোডে হ্যাপিং করা এবং সংরক্ষিত রেজিস্টারগুলির সাথে ডডলিংয়ের মতো কৌশলগুলি ছাড় করি। আইএমও, এটি জাভা নয়। হাইপোথিটিক্যালি, এই জাতীয় জিনিসগুলি কোনও জেভিএম বাগের ফলস্বরূপ ঘটতে পারে ... তবে আমি প্রতিটি দেখার ত্রুটি প্রতিবেদন মনে করতে পারি না।

2 - আসলে, জেএলএস আচরণটি কী হবে তা বলে না, এবং এটি বাস্তবায়ন নির্ভর হতে পারে ... অন্যান্য বিষয়ের মধ্যে।


1

আপনি যখন কোনও পদ্ধতিতে nullরেফারেন্সের NullPointerExceptionজন্য আবেদন করেন তখন জাভা ভিএম থেকে ফেলে দেওয়া হবে। এটি স্পেসিফিকেশন অনুসারে তাই যদি আপনার জাভা ভিএম স্পষ্টতার সাথে কঠোরভাবে মেনে চলে তবে thisতা কখনই হবে না null


1

পদ্ধতিটি যদি স্থির হয় তবে কোনও কিছুই নেই this। যদি পদ্ধতিটি ভার্চুয়াল হয়, তবে thisনਾਲ হতে পারে না, কারণ পদ্ধতিটি কল করতে, রান-টাইমটির জন্য thisপয়েন্টারটি ব্যবহার করে ভিটিবেলটি উল্লেখ করা দরকার । যদি পদ্ধতিটি ভার্চুয়াল না হয় তবে হ্যাঁ, এটি সম্ভবthis নাল।

সি # এবং সি ++ নন-ভার্চুয়াল পদ্ধতিগুলিকে মঞ্জুরি দেয় তবে জাভাতে সমস্ত অ স্থিত পদ্ধতি ভার্চুয়াল হয়, তাই thisকখনই বাতিল হবে না।


0

tl; dr, "এটি" কেবলমাত্র একটি স্থিতিশীল পদ্ধতি থেকে কল করা যেতে পারে এবং আমরা সকলেই জানি যে একটি স্থিতিশীল পদ্ধতি কোনও ধরণের অবজেক্ট থেকে আহ্বান করা হয় যা শূন্য হতে পারে না।

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