জাভা নাল পরীক্ষা করুন কেন .aquals () এর পরিবর্তে == ব্যবহার করুন


125

জাভাতে আমাকে বলা হয়েছে যে নাল চেক করার সময় একটিটি .equals () এর পরিবর্তে == ব্যবহার করা উচিত। এই জন্য কারণ কি কি?


12
সবচেয়ে সহজ জিনিস হ'ল নাল চেক করার চেষ্টা করে equals()দেখুন। আপনি যখন চেষ্টা করবেন তা তাত্ক্ষণিকভাবে স্পষ্ট হয়ে
উঠবে

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

উত্তর:


179

তারা দুটি সম্পূর্ণ ভিন্ন জিনিস। ==কোনও ভেরিয়েবল দ্বারা অন্তর্ভুক্ত থাকা অবজেক্ট রেফারেন্সের তুলনা করে। সাম্য বলতে কী বোঝায় তার চুক্তি অনুসারে .equals()দুটি বস্তু সমান কিনা তা পরীক্ষা করে দেখুন । দুটি স্বতন্ত্র বস্তুর দৃষ্টান্ত তাদের চুক্তি অনুসারে "সমান" হওয়া সম্পূর্ণভাবে সম্ভব। এবং তারপরে ছোটখাটো বিশদ আছে যেহেতু equalsএকটি পদ্ধতি, আপনি যদি কোনও nullরেফারেন্সে এটি চাওয়ার চেষ্টা করেন তবে আপনি একটি পাবেন NullPointerException

এই ক্ষেত্রে:

class Foo {
    private int data;

    Foo(int d) {
        this.data = d;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null || other.getClass() != this.getClass()) {
           return false;
        }
        return ((Foo)other).data == this.data;
    }

    /* In a real class, you'd override `hashCode` here as well */
}

Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances

System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition

Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it

System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything

System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null

মানে public int data?
Jue Queue

@ এক্সপচ: না, আমি সাধারণত সর্বজনীন ক্ষেত্রগুলি তৈরি করি না (যদিও এটি উদাহরণস্বরূপ কোনওভাবেই গুরুত্বপূর্ণ নয়)। কেন?
টিজে ক্রাউডার

@ টিজে ক্রাউডার "এগুলি দুটি সম্পূর্ণ ভিন্ন জিনিস .." সাধারণভাবে হ্যাঁ। তবে, আমার বোধগম্যতা যদি সঠিক হয় তবে উভয়ের ডিফল্ট বাস্তবায়ন একই। উত্স কোডটি দেখে, .equals () মূলত একটি == চেক করে। hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…
আয়ুশ

1
@ আয়ুশ - এটি Objectহ্যাঁ, এটি ডিফল্ট । যদিও এটি জেডিকে ক্লাসের একটি বিশাল সংখ্যক দ্বারা উপেক্ষা করা হয়েছে। তবে বিষয়টি বাস্তবায়ন সম্পর্কে নয়, এটি শব্দার্থবিদ্যার বিষয়ে। (পার্শ্ব দ্রষ্টব্য: জেডিকে 7 খুব পুরানো))
টিজে ক্রোডার

ঠিক আছে, এটি বোঝায় যে, কেবল স্পষ্ট করতে চেয়েছিলেন।
আয়ুশ

38

যদি আপনি ডাকা .equals()উপর nullআপনি পাবেনNullPointerException

সুতরাং এটি প্রয়োগ করার পদ্ধতিটি প্রয়োগ করার আগে সর্বদা নালিশতা পরীক্ষা করার পরামর্শ দেওয়া হয়

if(str!=null && str.equals("hi")){
 //str contains hi
}  

এছাড়াও দেখুন


34
আপনার উদাহরণ হিসাবে সাধারণত আরও ভাল লেখা হয় if ("hi".equals(str))
কলিনড

3
@ user368186: সমান পদ্ধতিতে নাল চেক অন্তর্ভুক্ত কিনা তা বিন্দু নয়। যদি আপনার অবজেক্টের রেফারেন্স নাল হয়, তবে কলটি সমান পদ্ধতিতে প্রবেশ না করেই someObject.equals(null)একটি বাড়িয়ে তুলবে NullPointerException
ডেভ কোস্টা

2
@ কলিন্ড সম্মত হলেন এখানে কেবল প্রদর্শিত
জিগার জোশী

2
সর্বদা সর্বদাই নালগুলি এড়াতে পরামর্শ দেওয়া হয়, যাতে আপনার নাল চেকের কোনও প্রয়োজন হয় না;)।
fwielstra

2
আপনি সর্বদা ব্যবহার করতে পারবেন Objects.equals(a, b)এটি নালপয়েন্টারএক্সেপশনকে বাড়িয়ে তুলবে না, তবে এটি এখনও "এ" এবং "বি" এর "সমান" পদ্ধতির উপর নির্ভর করে
ডোমিনিক মিন্ক

29

গৃহীত উত্তর ছাড়াও ( https://stackoverflow.com/a/4501084/6276704 ):

জাভা 1.7 যেহেতু, আপনি যদি দুটি বস্তু যা শূন্য হতে পারে তার তুলনা করতে চান, তবে আমি এই ফাংশনটির প্রস্তাব দিচ্ছি:

Objects.equals(onePossibleNull, twoPossibleNull)

java.util.Objects

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

যেহেতু: 1.7


2
শুধু এটা আরো অন্যদের জন্য দৃশ্যমান করতে (chin90 এর উত্তর বা দেখতে JavaDoc ): Objects.equals(null, null)ফিরে আসবে true- মনে রাখবেন যে।
টমাস

20

জাভাতে 0 বা নাল সরল ধরণের এবং অবজেক্ট নয়।

পদ্ধতিটি সমান () সাধারণ ধরণের জন্য নির্মিত হয় না। সাধারণ প্রকারের সাথে == মেলা যায়।


4
প্রকৃত উত্তরের জন্য আপভোট করুন যা সুস্পষ্ট "নালপয়েন্টারএক্সেপশন ফিরিয়ে দেওয়া হবে" হার্প ডার্প উত্তরটির বিপরীতে সবচেয়ে কার্যকর।
volk

4
foo.equals(null)

ফু নাল হলে কী হয়?

আপনি একটি নালপয়েন্টার এক্সসেপশন পান।


3

যদি কোনও অবজেক্ট ভেরিয়েবল নাল হয় তবে তার উপর কেউ সমান () পদ্ধতি কল করতে পারে না, সুতরাং নালটির একটি অবজেক্ট রেফারেন্স চেক উপযুক্ত।


2

যদি আপনি নাল অবজেক্ট রেফারেন্সের সমান কল করার চেষ্টা করেন, তবে আপনি নাল পয়েন্টার ব্যতিক্রম নিক্ষেপ করবেন।


2

সূত্রের মতে ডিফল্ট পদ্ধতি প্রয়োগের জন্য কী ব্যবহার করা উচিত তা বিবেচ্য নয়:

public boolean equals(Object object) {
    return this == object;
}

তবে আপনি equalsকাস্টম ক্লাসে নিশ্চিত হতে পারবেন না ।


এটি গুরুত্বপূর্ণ, যেহেতু equalsকেবলমাত্র ফিরে আসতে পারে falseবা কোনও কারণ হতে পারে NullPointerException(বা ওভাররডেন equalsপদ্ধতিটি বাজে কথা হলে কিছু আলাদা )।
টম

2

যদি আমরা => .Equals পদ্ধতি ব্যবহার করি

if(obj.equals(null))  

// Which mean null.equals(null) when obj will be null.

যখন আপনার আপত্তি নাল হবে এটি নাল পয়েন্ট ব্যতিক্রম ছুঁড়ে ফেলবে।

সুতরাং আমাদের ব্যবহার করা উচিত ==

if(obj == null)

এটি উল্লেখগুলি তুলনা করবে।


2

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

String firstname = null;
String lastname = null;

if(Objects.equals(firstname, lastname)){
    System.out.println("equal!");
} else {
    System.out.println("not equal!");
}

উপরে স্নিপেট সমান ফিরে আসবে!


যেমন জাভাডক বলেছেন ( এগুলি পড়া সর্বদা বুদ্ধিমান): Consequently, if both arguments are null, true is returned. ...:)
টমাস

1

সমান হ'ল অবজেক্ট বর্গ থেকে প্রাপ্ত একটি ফাংশন, এই ফাংশনটি শ্রেণীর আইটেমগুলির সাথে তুলনা করে। যদি আপনি এটি শূন্যের সাথে ব্যবহার করেন তবে এটি মিথ্যা কারণ দেখায় কারণ শ্রেণীর সামগ্রী নাল নয়। অতিরিক্ত == একটি বস্তুর রেফারেন্স তুলনা করে।


ঠিক আছে, ফলাফলটি কেবলমাত্র falseবা NullPointerException(যদি equalsকোনও খারাপ কিছুকেই বেশি করা না হয়) হতে পারে।
টম

1

এখানে একটি উদাহরণ যেখানে str != nullকিন্তু str.equals(null)যখন ব্যবহারorg.json

 JSONObject jsonObj = new JSONObject("{field :null}");
 Object field = jsonObj.get("field");
 System.out.println(field != null);        // => true
 System.out.println( field.equals(null)); //=> true
 System.out.println( field.getClass());  // => org.json.JSONObject$Null




সম্পাদনা: এখানে org.json.JSONObject $ নাল শ্রেণি:

/**
 * JSONObject.NULL is equivalent to the value that JavaScript calls null,
 * whilst Java's null is equivalent to the value that JavaScript calls
 * undefined.
 */
private static final class Null {

    /**
     * A Null object is equal to the null value and to itself.
     *
     * @param object
     *            An object to test for nullness.
     * @return true if the object parameter is the JSONObject.NULL object or
     *         null.
     */
    @Override
    public boolean equals(Object object) {
        return object == null || object == this;
    }  
}

এখানে বিষয়টি field.equals(null)সত্য যে ফিরে আসে। এটি স্বাভাবিক জাভা আচরণ ভেঙে দেয় এবং তাই বিভ্রান্তিকর। এটি কেবলমাত্র field.equals("null")আমার দৃষ্টিকোণে কাজ করা উচিত । লাইব্রেরি বিকাশকারীরা কেন ভেবেছিলেন তা আমি জানি না, এটি সমর্থন করা ভাল।
টম

বিটিডব্লিউ, আপনার প্রথম বাক্যে ব্যাকরণের সমস্যা রয়েছে এবং এটির অর্থ আপনি কী বোঝাতে চান তা অস্পষ্ট। আপনি কি এটি বলতে না "এখানে একটি উদাহরণ কোথায় str != nullএবং str.equals(null)রিটার্ন trueযখন ব্যবহার org.json ।"?
টম

আমি মনে করি এটি কারণ এই jsonObject"ক্ষেত্র" কীটি কেন fieldতাই নাল নয়, এটিতে একটি রেফারেন্স রয়েছে যা এতে json.org.JSONObject$Null অবজেক্টটি রয়েছে
ডিনা

হ্যাঁ, তবে আমি এর Nullমতো nullব্যবহার করব "null"না এবং এর পরিবর্তে ব্যবহার করব । তবে আমার ধারণা স্ট্রিংয়ের প্রয়োজনীয়তা এড়াতে তারা এটি করেছে। তবে এমনকি এই lib সঙ্গে, field.equals(null)এখনও প্রায় সর্বদা একটি সমস্যা: পি।
টম

0

সুতরাং আমি কখনই বিভ্রান্ত হব না এবং এই সমাধানটি নিয়ে সমস্যাগুলি এড়াতে পারি না:

if(str.trim().length() <=0 ) {
   // is null !
}

5
যদি str নাল হয় তবে এটি একটি
এনপিই

অতিরিক্তভাবে একটি খালি স্ট্রিং ( ""দৈর্ঘ্য 0 হওয়া) একটি nullরেফারেন্সের (যেমন কোনও স্ট্রিং নয়) থেকে সম্পূর্ণ আলাদা is
টমাস

0

আমি কাল রাতে এই মামলার মুখোমুখি হয়েছি।
আমি এটি সহজভাবে নির্ধারণ করি যে:

উপস্থিত না থাকার সমান () মেথড জন্য নাল
সুতরাং, আপনি করতে পারবেন না ডাকা একটি অবিদ্যমান পদ্ধতি আছে যদি না
- >>> এটা কেন আমরা ব্যবহার জন্য কারণ == চেক করতে নাল


0

আপনার কোড ডেমিটারের আইন ভঙ্গ করে। এ কারণেই নকশাকে নিজেই রিফ্যাক্টর করা ভাল। কার্যকারিতা হিসাবে, আপনি ptionচ্ছিক ব্যবহার করতে পারেন

   obj = Optional.ofNullable(object1)
    .map(o -> o.getIdObject11())
    .map(o -> o.getIdObject111())
    .map(o -> o.getDescription())
    .orElse("")

উপরেরটি হ'ল কোনও অবজেক্টের হায়ারার্কি পরীক্ষা করা যা সহজভাবে ব্যবহার করুন check

Optional.ofNullable(object1) 

আপনার যদি চেক করার একমাত্র অবজেক্ট থাকে

আশাকরি এটা সাহায্য করবে !!!!


-3

আপনি সবসময় করতে পারে

if (str == null || str.equals(null))

এটি প্রথমে অবজেক্টের রেফারেন্স চেক করবে এবং তারপরে রেফারেন্সটি শূন্য নয় এমনটি নিজেই পরীক্ষা করবে check


if (str == নাল || str.equals (নাল) || str.equals (""))
লু মর্দা

আমি আপনার উত্তরটি ব্যবহার করেছি এবং একটি খালি স্ট্রিংয়ের জন্য একটি চেক যোগ করেছি! যদি আমি ভুল না হয় তবে নাল এবং "" একই জিনিস নয়।
লু মর্দা

4
শূন্যতার জন্য ২ য় চেক যুক্ত করা কি সম্পূর্ণ বেপরোয়া নয়?
জাস্টিন রোয়ে

2
@ জাস্টিনরো এটি কেবল অপ্রয়োজনীয় নয়, এটি খুব ভুলও নয়। দয়া করে, কখনও এরকম কিছু করবেন না x.equals(null)
টম

@Tom, JustinRowe দয়া করে উপরে আমার উত্তর দেখতে কেন এই অপ্রয়োজনীয় কিংবা সম্পূর্ণ আবর্জনা নয় stackoverflow.com/questions/4501061/...
Dina
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.