এড়ানো! = নাল বিবৃতি


4014

আমি object != nullএড়াতে অনেক ব্যবহার করি NullPointerException

এর কোন ভাল বিকল্প আছে কি?

উদাহরণস্বরূপ আমি প্রায়শই ব্যবহার করি:

if (someobject != null) {
    someobject.doCalc();
}

এটি উপরের স্নিপেটে অবজেক্টটির NullPointerExceptionজন্য পরীক্ষা করে someobject

মনে রাখবেন যে গৃহীত উত্তরটি পুরানো হতে পারে, আরও সাম্প্রতিক পদ্ধতির জন্য https://stackoverflow.com/a/2386013/12943 দেখুন।


120
@ শেরভিন উত্সাহিত নাল কোডটি কম বোধগম্য এবং কম নির্ভরযোগ্য করে তুলেছে।
টম হাটিন -

44
এলভিস অপারেটরগুলির প্রস্তাব দেওয়া হয়েছিল তবে দেখে মনে হচ্ছে এটি জাভা 7 তে হবে না । খুব খারাপ, ?. ?: এবং? [] অবিশ্বাস্য সময় সাশ্রয়কারী।
স্কট

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

13
আমি এখন স্কালাকে ব্যবহার করার জন্য এটি একটি কারণ। স্কালায় সমস্ত কিছুই শুল্কযুক্ত নয়। যদি আপনি "কিছুই না" পাস করার বা ফেরত দেওয়ার অনুমতি দিতে চান, তবে আপনাকে কেবল টি আলস আর্গুমেন্ট বা রিটার্নের ধরণের পরিবর্তে স্পষ্টভাবে অপশন [টি] ব্যবহার করতে হবে।
থেকবস্তি

11
@ সোফট প্রকৃতপক্ষে, স্কালার অদ্ভুত Optionধরণের ভাষা নিয়ন্ত্রণ বা অস্বীকার করার ভাষার অনীহা দ্বারা বিস্মিত হয়েছে null। আমি হ্যাকারনিউজে এটি উল্লেখ করেছি এবং নিম্নচেতন হয়ে গিয়েছিলাম এবং বলেছিলাম যে "স্ক্যালায় কেউ যেভাবে নাল ব্যবহার করে না"। কী অনুমান করুন, আমি ইতিমধ্যে সহকর্মী-লিখিত স্কালায় নাল খুঁজে পাচ্ছি। হ্যাঁ, তারা "এটি ভুল করছে" এবং এ সম্পর্কে তাদের অবশ্যই শিক্ষিত হতে হবে, তবে সত্যটি এখনও রয়ে গেছে যে ভাষার টাইপ সিস্টেমটি আমাকে এ থেকে রক্ষা করা উচিত এবং তা হয় না :(
এন্ড্রেস এফ

উত্তর:


2642

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

এটি অন্য উপায়ে বলতে গেলে দুটি উদাহরণ রয়েছে যেখানে নাল চেকিং আসে:

  1. চুক্তির শর্তাবলী যেখানে নাল একটি বৈধ প্রতিক্রিয়া; এবং

  2. যেখানে এটি কোনও বৈধ প্রতিক্রিয়া নয়।

(2) সহজ। হয় assertবিবৃতি ব্যবহার ( দৃ as়তা ) বা ব্যর্থতা অনুমতি (উদাহরণস্বরূপ, NullPointerException )। জোর দেওয়াগুলি একটি উচ্চ-নিরুত্বল জাভা বৈশিষ্ট্য যা 1.4 এ যুক্ত হয়েছিল। বাক্য গঠনটি হ'ল:

assert <condition>

অথবা

assert <condition> : <object>

যেখানে <condition>বুলিয়ান এক্সপ্রেশন এবং <object>এমন একটি বস্তু যা এর toString()পদ্ধতির আউটপুট ত্রুটির সাথে যুক্ত হবে।

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

এই ক্ষেত্রে দৃser়তা ব্যবহার না করা ঠিক আছে কারণ কোডটি কেবলমাত্র ব্যর্থ হবে, যা যদি আপনি দৃ use়তা ব্যবহার করেন তবে কি হবে। পার্থক্যটি হ'ল দৃ as়তার সাথে এটি খুব তাড়াতাড়ি ঘটতে পারে, আরও অর্থবহ উপায়ে এবং সম্ভবত অতিরিক্ত তথ্যের সাথে, যা আপনি যদি প্রত্যাশা না করেন তবে কেন এটি ঘটেছে তা নির্ধারণ করতে আপনাকে সহায়তা করতে পারে।

(1) একটু কঠিন। আপনি যে কোডটি কল করছেন তার যদি আপনার কোনও নিয়ন্ত্রণ না থাকে তবে আপনি আটকে রয়েছেন। যদি নাল একটি বৈধ প্রতিক্রিয়া হয় তবে আপনাকে এটি পরীক্ষা করতে হবে।

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

অ-সংগ্রহের সাথে এটি আরও শক্ত হতে পারে। এটি উদাহরণ হিসাবে বিবেচনা করুন: আপনার যদি এই ইন্টারফেসগুলি থাকে:

public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

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

একটি বিকল্প সমাধান হ'ল কখনই নাল ফিরে না আসা এবং পরিবর্তে নাল অবজেক্ট প্যাটার্নটি ব্যবহার করুন :

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

তুলনা করা:

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}

প্রতি

ParserFactory.getParser().findAction(someInput).doSomething();

এটি একটি আরও ভাল নকশা কারণ এটি আরও সংক্ষিপ্ত কোডের দিকে নিয়ে যায়।

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

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

অথবা আপনি যদি মনে করেন যে চেষ্টা / ধরার ব্যবস্থাটি খুব কুৎসিত হয় তার চেয়ে আপনার কিছুই না করে আপনার ডিফল্ট ক্রিয়াটি ব্যবহারকারীর প্রতিক্রিয়া সরবরাহ করে provide

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}

631
আমি আপনার ডিও_অনথিং কর্মের জন্য বিবৃতিগুলির সাথে একমত নই। যদি অনুসন্ধানের ক্রিয়া পদ্ধতিটি কোনও ক্রিয়া না খুঁজে পায়, তবে নাল ফিরিয়ে দেওয়া সঠিক কাজ। আপনি আপনার কোডে একটি ক্রিয়া "পেয়েছেন" যা সত্যিকার অর্থে পাওয়া যায় নি, যা ব্যবহারের যোগ্য ক্রিয়া সন্ধানের জন্য পদ্ধতির নীতি লঙ্ঘন করে।
MetroidFan2002

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

92
এখানে পরবর্তী উদাহরণটি হ'ল আইআইআরসি, নাল অবজেক্ট ডিজাইনের ধরণ।
স্টিভেন এভার্স 4

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

35
সংক্ষিপ্ত মানের কোড সমান নয়। আমি দুঃখিত আপনি তাই মনে করেন। আপনার কোড এমন পরিস্থিতিগুলি লুকিয়ে রাখে যেখানে কোনও ত্রুটি সুবিধাজনক হবে।
gshauger

634

যদি আপনি ব্যবহার (বা ব্যবহার করার পরিকল্পনা করা) -এর মত একটি জাভা আইডিই JetBrains IntelliJ ধারণা , অন্ধকার বা Netbeans বা findbugs মত একটি হাতিয়ার তাহলে আপনি এই সমস্যা সমাধানের জন্য টীকা ব্যবহার করতে পারেন।

মূলত, আপনি পেয়েছেন @Nullableএবং পেয়েছেন @NotNull

আপনি এই পদ্ধতি এবং পরামিতি ব্যবহার করতে পারেন:

@NotNull public static String helloWorld() {
    return "Hello World";
}

অথবা

@Nullable public static String helloWorld() {
    return "Hello World";
}

দ্বিতীয় উদাহরণটি সংকলন করবে না (ইন্টেলিজ আইডিইএ)।

আপনি যখন helloWorld()অন্য কোনও কোডের প্রথম ফাংশনটি ব্যবহার করেন :

public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}

এখন ইন্টেলিজ আইডিইএ সংকলক আপনাকে বলবে যে চেকটি অকেজো, যেহেতু helloWorld()ফাংশনটি আর ফিরে আসবে না null

প্যারামিটার ব্যবহার করে

void someMethod(@NotNull someParameter) { }

আপনি যদি কিছু লিখেন:

someMethod(null);

এটি সংকলন করবে না।

ব্যবহারের শেষ উদাহরণ @Nullable

@Nullable iWantToDestroyEverything() { return null; }

এটা করছি

iWantToDestroyEverything().something();

এবং আপনি নিশ্চিত হতে পারেন যে এটি ঘটবে না। :)

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

ইন্টেলিজ আইডিইএ 10.5 এবং তারপরে, তারা অন্য যে কোনও @Nullable @NotNullবাস্তবায়নের জন্য সমর্থন যোগ করেছে ।

ব্লগ পোস্ট দেখুন আরো নমনীয় এবং কনফিগার @ Nullable / @ NotNull টীকা


119
@NotNull, @Nullableএবং অন্যান্য শালীন টীকাগুলি JSR 305 এর অংশ । আপনি ফাইন্ডব্যাগগুলির মতো সরঞ্জামগুলির সাথে সম্ভাব্য সমস্যাগুলি সনাক্ত করতে এটি ব্যবহার করতে পারেন ।
জ্যাসেক এস

32
আমি আশ্চর্যজনকভাবে বিরক্তিকর বলে মনে করি যে প্যাকেজে @NotNull& @Nullableইন্টারফেসগুলি লাইভ রয়েছে com.sun.istack.internal। (আমি অনুমান করি যে আমি com.sun কে মালিকানাধীন এপিআই ব্যবহারের বিষয়ে সতর্কতার সাথে জড়িত))
জোনিক

20
কোড পোর্টেবিলিটিটি জেটব্রেনগুলির সাথে বাতিল হয়ে যায় ide আদর্শ স্তরে বাঁধা দেওয়ার আগে আমি দুবার (বর্গক্ষেত্র) চিন্তা করব L লাইক জেসেক এস বলেছেন যে তারা যেভাবেই আমি জেএসআর 303 বলে ভেবেছিলাম তারা জেএসআরের অংশ।
জাভা কা বেবি

10
আমি সত্যিই মনে করি না যে কাস্টম সংকলক ব্যবহার করা এই সমস্যার একটি কার্যকর সমাধান।
শিবান ড্রাগন

64
টীকাগুলি সম্পর্কে ভাল জিনিস যা @NotNullএবং @Nullableতা হ'ল উত্স কোডটি এমন কোনও সিস্টেম দ্বারা নির্মিত হয় যা সেগুলি বোঝে না। সুতরাং, বাস্তবে, যুক্তিটি যে কোডটি পোর্টেবল নয় তা অবৈধ হতে পারে - আপনি যদি এমন কোনও সিস্টেম ব্যবহার করেন যা এই টীকাগুলি সমর্থন করে এবং বুঝতে পারে তবে আপনি কঠোর ত্রুটি পরীক্ষার অতিরিক্ত সুবিধা পেয়ে যাবেন, অন্যথায় আপনি এর কম পান তবে আপনার কোডটি এখনও হওয়া উচিত জরিমানা তৈরি করুন, এবং আপনার চলমান প্রোগ্রামের গুণমান হ'ল একই, কারণ এই টীকাগুলি কোনওভাবেই রানটাইমে কার্যকর করা হয়নি। এছাড়াও, সমস্ত
সংকলকগুলি

321

নাল-মান অনুমোদিত না হলে

যদি আপনার পদ্ধতিটিকে বাহ্যিকভাবে বলা হয় তবে এরকম কিছু দিয়ে শুরু করুন:

public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }

তারপরে, এই পদ্ধতিটির বাকী অংশে, আপনি জানবেন যে objectএটি নাল নয়।

যদি এটি কোনও অভ্যন্তরীণ পদ্ধতি হয় (কোনও এপিআইয়ের অংশ নয়) তবে কেবল নথি করুন যে এটি বাতিল হতে পারে না এবং এটিই।

উদাহরণ:

public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}

তবে, যদি আপনার পদ্ধতিটি কেবলমাত্র মানটি পাস করে এবং পরবর্তী পদ্ধতিটি এটি পাস করে তবে এটি সমস্যাযুক্ত হতে পারে। সেক্ষেত্রে আপনি উপরের মত যুক্তিটি পরীক্ষা করতে চাইতে পারেন।

যদি নাল অনুমতি দেওয়া হয়

এটি সত্যই নির্ভর করে। যদি মনে হয় যে আমি প্রায়শই এরকম কিছু করি:

if (object == null) {
  // something
} else {
  // something else
}

সুতরাং আমি শাখা করি, এবং দুটি সম্পূর্ণ ভিন্ন জিনিস করি। কোনও কুৎসিত কোড স্নিপেট নেই, কারণ আমার সত্যিকার অর্থে ডেটার উপর নির্ভর করে দুটি আলাদা জিনিস করা দরকার। উদাহরণস্বরূপ, আমার কি ইনপুটটিতে কাজ করা উচিত, বা আমার একটি ভাল ডিফল্ট মান গণনা করা উচিত?


" if (object != null && ..." আইডিয়ামটি ব্যবহার করা আমার পক্ষে আসলে বিরল ।

আপনি সাধারণত উদাহরণস্বরূপ যেখানে আইডিয়মটি ব্যবহার করেন তার উদাহরণগুলি দেখানো হলে আপনাকে উদাহরণ দেওয়া আরও সহজ হতে পারে।


94
অবৈধআর্গুমেন্টএক্সেপশন নিক্ষেপ করার কী লাভ? আমি মনে করি নালপয়েন্টার এক্সসেপশনটি আরও পরিষ্কার হবে এবং আপনি নিজে নাল-চেক না করলে এটিও ছুঁড়ে ফেলা হবে। আমি হয় আসক্তি বা কিছুই কিছুই ব্যবহার করব।
এক্সেল

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

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

8
একটি সুরক্ষা গর্ত? জেডিকে এই জাতীয় কোডে পূর্ণ। আপনি যদি ব্যবহারকারীকে স্ট্যাকট্রেসগুলি দেখতে না চান তবে কেবল তাদের অক্ষম করুন। আচরণটি নথিভুক্ত নয় বলে কেউ জোর দিয়েছিল। মাইএসকিউএল সিতে লেখা আছে যেখানে নাল পয়েন্টারকে ডিফারেন্স করা অপরিজ্ঞাত আচরণ, ব্যতিক্রম ছোঁড়ার মতো কিছুই নয়।
fgb

8
throw new IllegalArgumentException("object==null")
থরবজর্ন রাভন অ্যান্ডারসন

238

বাহ, আমি যখন সুপারিশ করার 57 টি ভিন্ন উপায় পেয়েছি তখন আমি অন্য উত্তর যুক্ত করতে প্রায় ঘৃণা NullObject patternকরি, তবে আমি মনে করি যে এই প্রশ্নে আগ্রহী কিছু লোক জানতে চান যে জাভা 7 এর টেবিলে "নাল-সেফ" যুক্ত করার প্রস্তাব রয়েছে " যদি না-সমান-নাল যুক্তির জন্য প্রবাহিত বাক্য গঠন পরিচালনা করে"

অ্যালেক্স মিলার প্রদত্ত উদাহরণটি এরকম দেখাচ্ছে:

public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  

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


আপডেট করুন: একটি সরকারী প্রস্তাব জাভা 7 একটি নাল-নিরাপদ অপারেটর জন্য অধীনে জমা দেওয়া হয়েছে প্রকল্প মুদ্রা। সিনট্যাক্সটি উপরের উদাহরণের চেয়ে কিছুটা আলাদা তবে এটি একই ধারণা।


আপডেট: নাল-সেফ অপারেটরের প্রস্তাব এটি প্রকল্পের মুদ্রায় পরিণত করতে পারেনি। সুতরাং, আপনি জাভা 7 এ এই সিনট্যাক্সটি দেখছেন না।


20
আমি মনে করি এটি ভুল। নির্দিষ্ট করার একটি উপায় থাকতে হবে যে প্রদত্ত ভেরিয়েবলটি সর্বদা নন-নাল।
থরবজর্ন রাভন অ্যান্ডারসন


9
আকর্ষণীয় ধারণা কিন্তু বাক্য গঠনটি অযৌক্তিক; আমি চাই না যে প্রতিটি জয়েন্টে প্রশ্নবোধক পূর্ণ একটি কোডবেস পিনযুক্ত।
রব

7
এই অপারেটর গ্রোভিতে বিদ্যমান , সুতরাং যারা এটি ব্যবহার করতে চান তাদের এখনও বিকল্প হিসাবে এটি রয়েছে।
মুহাদ

8
এটি আমার মধ্যে সবচেয়ে বুদ্ধিমান ধারণা idea এটি সি সিনট্যাক্সের প্রতিটি সংবেদনশীল ভাষায় যুক্ত করা উচিত। আমি বরং সারাদিন স্ক্রিনফুল লাইনের মাধ্যমে স্ক্রল করা বা "গার্ড ক্লজ" ডজ করার চেয়ে সর্বত্র "প্রশ্ন প্রশ্ন চিহ্নগুলি" করব।
ভিক্টর

196

যদি অপরিজ্ঞাত মানগুলি অনুমোদিত না হয়:

সম্ভাব্য নাল ডিফারেন্সিং সম্পর্কে আপনাকে সতর্ক করতে আপনি আপনার আইডিই কনফিগার করতে পারেন। উদাহরণস্বরূপ ইক্লিপস, পছন্দসমূহ> জাভা> সংকলক> ত্রুটি / সতর্কতা / নাল বিশ্লেষণ দেখুন

যদি অপরিজ্ঞাত মানগুলি অনুমোদিত হয়:

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

  • এটি কোনও ইনপুট বা আউটপুট বিদ্যমান কিনা তা স্পষ্ট করে এপিআইতে বলা হয়েছে।
  • সংকলক আপনাকে "অপরিজ্ঞাত" কেস পরিচালনা করতে বাধ্য করে।
  • বিকল্পটি একটি মোনাড , সুতরাং ভার্বোজ নাল চেকিংয়ের দরকার নেই, মানটি (উদাহরণ) নিরাপদে ব্যবহার করতে কেবল মানচিত্র / ফোরচ / গেটঅরলেস বা অনুরূপ সংযোজক ব্যবহার করুন ।

জাভা 8 এর একটি অন্তর্নির্মিত Optionalবর্গ রয়েছে (প্রস্তাবিত); পূর্ববর্তী সংস্করণে জন্য, সেখানে গ্রন্থাগার বিকল্প আছে উদাহরণস্বরূপ পেয়ারা এর Optionalবা FunctionalJava এর Option। তবে অনেকগুলি কার্যক্ষম শৈলীর নিদর্শনগুলির মতো, জাভাতে বিকল্প (এমনকি 8) ব্যবহার করার ফলে বেশ কয়েকটি বয়লারপ্লেটের ফলস্বরূপ হয়, যা আপনি কম ভার্বোস জেভিএম ভাষা ব্যবহার করে হ্রাস করতে পারেন, উদাহরণস্বরূপ স্কালা বা এক্সেন্ডেন্ড।

আপনার যদি এমন কোনও এপিআই নিয়ে কাজ করতে হয় যা নালাগুলি ফিরে আসতে পারে তবে আপনি জাভাতে বেশি কিছু করতে পারবেন না। এক্সতেন্ড এবং গ্রোভির এলভিস অপারেটর ?: এবং নাল-সেফ ডেরিফারেন্স অপারেটর রয়েছে ?. তবে নোট করুন যে এটি নাল রেফারেন্সের ক্ষেত্রে বাতিল হয়ে যায়, সুতরাং এটি নালকে সঠিকভাবে পরিচালনা করতে "স্থগিত" করে।


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


1
... এবং এটা না (এখনও) মানচিত্রে আছে কিংবা flatMap: download.java.net/jdk8/docs/api/java/util/Optional.html
thSoft

3
;চ্ছিক প্যাটার্নটি কোনও কিছুই সমাধান করে না; একটি সম্ভাব্য নাল বস্তুর পরিবর্তে, এখন আপনার দুটি আছে।
বোয়ান

1
@ বনান, যদি যত্ন সহ ব্যবহার করা হয় তবে আপনি আপনার সমস্ত এনপিই সমস্যা সমাধান করবেন। যদি তা না হয় তবে আমি অনুমান করি যে এখানে একটি "ব্যবহার" সমস্যা রয়েছে।
লুই এফ।

189

শুধুমাত্র এই পরিস্থিতির জন্য -

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

if ( foo.equals("bar") ) {
 // ...
}

NullPointerExceptionযদি fooঅস্তিত্ব না থাকে একটি ফলাফল ।

আপনি যদি Stringএটিকে এর সাথে তুলনা করেন তবে আপনি এড়াতে পারেন :

if ( "bar".equals(foo) ) {
 // ...
}

42
আমি সম্মত - শুধুমাত্র এই পরিস্থিতিতে। আমি এমন প্রোগ্রামারগুলিকে দাঁড়াতে পারছি না যা এগুলি পরবর্তী অপ্রয়োজনীয় স্তরে নিয়ে গেছে এবং যদি লিখতে পারে (নাল! = মাইভার) ... কেবল আমার কাছে কুৎসিত দেখায় এবং কোনও উদ্দেশ্য করে না!
অ্যালেক্স ওয়ার্ডেন

20
এটি একটি সাধারণ ভাল অভ্যাসের সম্ভবত সবচেয়ে বেশি ব্যবহৃত একটি বিশেষ উদাহরণ: যদি আপনি এটি জানেন তবে সর্বদা করুন <object that you know that is not null>.equals(<object that might be null>);equalsযদি আপনি চুক্তিটি জানেন এবং এই পদ্ধতিগুলি nullপরামিতিগুলি পরিচালনা করতে পারে তবে এটি অন্য পদ্ধতিগুলির জন্য কাজ করে ।
স্টিফ

9
এটি যোদা কন্ডিশনের বিষয়ে আমি প্রথম দেখেছি যা বাস্তবে অর্থবোধ করে
ইরিন ড্রামমন্ড

6
নালপয়েন্টারএক্সেপশনগুলি কোনও কারণে নিক্ষেপ করা হয়। এগুলি নিক্ষিপ্ত করা হয়েছে কারণ কোনও বস্তু নাল যেখানে এটি হওয়া উচিত নয়। সমস্যাটি লুকান না, এটি ফিক্স করা প্রোগ্রামারদের কাজ।
অলিভার ওয়াটকিন্স

1
চেষ্টা-ক্যাট-ডু কিছুই সমস্যাটি আড়াল করে না, ভাষাতে চিনির অনুপস্থিতি প্রায় কাজ করার জন্য এটি একটি বৈধ অভ্যাস।
ইকক্স

167

জাভা 8 এর সাথে নতুন java.util.Optionalক্লাস আসে যা যুক্তিযুক্তভাবে কিছু সমস্যার সমাধান করে। কমপক্ষে কেউ বলতে পারেন যে এটি কোডের পঠনযোগ্যতার উন্নতি করে এবং পাবলিক এপিআইয়ের ক্ষেত্রে ক্লায়েন্ট বিকাশকারীকে এপিআইয়ের চুক্তি আরও পরিষ্কার করা হয়।

তারা এর মতো কাজ করে:

প্রদত্ত প্রকারের জন্য forচ্ছিক বস্তু ( Fruit) কোনও পদ্ধতির রিটার্ন টাইপ হিসাবে তৈরি করা হয়। এটি খালি থাকতে পারে বা কোনও Fruitবস্তু থাকতে পারে :

public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}

এখন এই কোডটি দেখুন যেখানে আমরা প্রদত্ত ফলের উদাহরণগুলির জন্য Fruit( fruits) একটি তালিকা অনুসন্ধান করি :

Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}

আপনি map()অপারেটরটি একটি গণনা সম্পাদন করতে - বা valueচ্ছিক বস্তুর কাছ থেকে একটি মান বের করতে পারেন । orElse()অনুপস্থিত মানগুলির জন্য আপনাকে ফ্যালব্যাক সরবরাহ করতে দেয়।

String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");

অবশ্যই, নাল / খালি মানের জন্য চেক এখনও প্রয়োজনীয়, তবে কমপক্ষে বিকাশকারী সচেতন যে মানটি খালি থাকতে পারে এবং চেক করতে ভুলে যাওয়ার ঝুঁকি সীমিত।

Optionalযখনই কোনও রিটার্ন মান শূন্য হতে পারে ব্যবহার করে স্ক্র্যাচ থেকে তৈরি একটি এপিআইতে এবং একটি সাধারণ প্লেট কেবল তখনই ফিরে আসে যখন এটি null(কনভেনশন) হতে পারে না , ক্লায়েন্ট কোডটি সাধারণ অবজেক্ট রিটার্ন মানগুলিতে নাল চেকগুলি ত্যাগ করতে পারে ...

অবশ্যই Optionalকোনও পদ্ধতি আর্গুমেন্ট হিসাবে ব্যবহার করা যেতে পারে, কিছু ক্ষেত্রে 5 বা 10 ওভারলোডিং পদ্ধতির চেয়ে alচ্ছিক আর্গুমেন্টগুলি ইঙ্গিত করার আরও ভাল উপায়।

Optionalঅন্যান্য সুবিধাজনক পদ্ধতি প্রস্তাব orElseদেয় যেমন ডিফল্ট মান ব্যবহারের অনুমতি দেয় এবং ল্যাম্বদা এক্সপ্রেশনগুলিরifPresent সাথে কাজ করে

আমি আপনাকে এই নিবন্ধটি পড়ার জন্য আমন্ত্রণ জানাচ্ছি (এই উত্তরটি লেখার জন্য আমার মূল উত্স) যাতে NullPointerException(এবং সাধারণভাবে নাল পয়েন্টার) সমস্যাযুক্ত পাশাপাশি আনা (আংশিক) সমাধানটি Optionalভালভাবে ব্যাখ্যা করা হয়েছে: জাভা অপশনাল অবজেক্টস


11
গুগলের পেয়ারা জাভা 6+ এর জন্য একটি alচ্ছিক ইমপ্লিমেন্ট রয়েছে।
ব্র্যাডলি গটফ্রাইড

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

এই ব্লগটিতে winter
চ্ছিক শীতকালীন.

4
লোকেরা কেন এটি করার if(optional.isPresent()){ optional.get(); }পরিবর্তে তাদের প্রবণতা রয়েছেoptional.ifPresent(o -> { ...})
সত্যেন্দ্র কুমার

1
সুতরাং, এপিআই চুক্তিভিত্তিক ইঙ্গিতগুলি ব্যতীত, এটি কেবলমাত্র কার্যনির্বাহী প্রোগ্রামারদের খাওয়ানো সম্পর্কে যারা অবিরাম চেইন পদ্ধতি উপভোগ করে।
পিষ্ট করুন

125

আপনি কী ধরণের অবজেক্টগুলি পরীক্ষা করছেন তার উপর নির্ভর করে আপনি অ্যাপাচি কমনের কিছু ক্লাস যেমন: অ্যাপাচি কমন্স ল্যাং এবং অ্যাপাচি কমন্স সংগ্রহগুলি ব্যবহার করতে পারবেন

উদাহরণ:

String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}

বা (আপনার যা পরীক্ষা করা দরকার তার উপর নির্ভর করে):

String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}

স্ট্রিংটিলস ক্লাসটি অনেকের মধ্যে একটি; কমন্সগুলিতে বেশ কয়েকটি ভাল ক্লাস রয়েছে যেগুলি নাল নিরাপদ ম্যানিপুলেশন করে।

আপনি অ্যাপাচি লাইব্রেরি অন্তর্ভুক্ত করার সময় JAVA- এ নাল ভ্যালিডেশন কীভাবে ব্যবহার করতে পারেন তার একটি উদাহরণ এখানে দেওয়া হয়েছে (কমন্স-ল্যাং-২.৪.জার)

public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}

এবং যদি আপনি স্প্রিং ব্যবহার করছেন, স্প্রিংয়েরও এর প্যাকেজে একই কার্যকারিতা রয়েছে, লাইব্রেরি দেখুন (বসন্ত-২.৪...জার)

বসন্ত থেকে এই স্ট্যাটিক ক্লাসফ কীভাবে ব্যবহার করবেন তার উদাহরণ (org.springframework.util.Assert)

Assert.notNull(validationEventHandler,"ValidationHandler not Injected");

5
এছাড়াও আপনি অ্যাপাচি কমন্স থেকে আরও জেনেরিক সংস্করণ ব্যবহার করতে পারেন, আমি যে প্যারামগুলি খুঁজে পেয়েছি তা পরীক্ষা করার জন্য পদ্ধতিগুলির শুরুতে বেশ কার্যকর। Validate.not নাল (অবজেক্ট, "অবজেক্ট অবশ্যই নাল হবে না"); commons.apache.org/lang/apidocs/org/apache/commons/lang/…
মনোজহনি

@ মোমোজোহ্নি বৈধকরণের মধ্যে কী কী? আমি জিজ্ঞাসা করছি কেননা এ্যাসেটটি জেভিএম এ সক্রিয় / নিষ্ক্রিয় হতে পারে এবং এটি প্রস্তাব দিচ্ছে যে এটি উত্পাদনে ব্যবহার করবেন না।
কুরাপিকা

এমনটি ভাবেন না - আমি বিশ্বাস করি বৈধতা ব্যর্থ হলে এটি কেবল একটি রানটাইম এক্সেক্সশন ছুড়ে দেয়
মনোজোহনি

96
  • আপনি যদি বিবেচনা করেন তবে কোনও বস্তু নালাগুলি না হওয়া উচিত (বা এটি কোনও বাগ) একটি আসক্তি ব্যবহার করুন।
  • যদি আপনার পদ্ধতিটি নাল প্যারামগুলি গ্রহণ না করে তবে এটি জাভাডকে বলুন এবং একটি দৃ as়তা ব্যবহার করুন।

আপনাকে অবজেক্টের জন্য পরীক্ষা করতে হবে! = নাল কেবল তখনই যদি আপনি কেসটি পরিচালনা করতে চান যেখানে অবজেক্টটি শূন্য হতে পারে ...

নাল / নোটনাল প্যারামগুলিতে সহায়তা করার জন্য জাভা 7-তে নতুন টিকা যুক্ত করার প্রস্তাব রয়েছে: http://tech.puredanger.com/java7/#jsr308



91

আমি "ব্যর্থ দ্রুত" কোডের ভক্ত। নিজেকে জিজ্ঞাসা করুন - যেখানে প্যারামিটারটি শূন্য রয়েছে সেই ক্ষেত্রে আপনি কি দরকারী কিছু করছেন? সেক্ষেত্রে আপনার কোডটি কী করা উচিত তার যদি আপনার কাছে পরিষ্কার উত্তর না থাকে ... তবে এটি প্রথম স্থানে কখনই শূন্য হওয়া উচিত নয়, তবে এটিকে উপেক্ষা করুন এবং নালপয়েন্টার এক্সেকশনটি নিক্ষেপ করার অনুমতি দিন। কলিং কোডটি কোনও এনপিইর মতোই অনুধাবন করবে যেমন এটি একটি অবৈধআর্গুমেন্ট এক্সেকশন হবে, তবে আপনার কোডটি অন্য কোনও অপ্রত্যাশিত পরিস্থিতি সম্পাদন করার চেষ্টা করার পরিবর্তে যদি কোনও এনপিই নিক্ষেপ করা হয় তবে ডিবাগ করা এবং কী ভুল হয়েছে তা বুঝতে বিকাশকারীদের পক্ষে সহজ হবে'll যুক্তি - যা পরিণামে যাইহোক আবেদন ব্যর্থ হয়।


2
দৃ use় প্রতিজ্ঞাগুলি ব্যবহার করা আরও ভাল, যেমন কন্ট্রাক্ট.নোট নাল (এবিসি, "এবিসি অবশ্যই নন-নাল হওয়া উচিত, এটি কি জাইজির সময় লোড করতে ব্যর্থ হয়েছিল?"); - এটি করার চেয়ে একটি আরও কমপ্যাক্ট উপায় (এবিসি! = নাল) new নতুন রানটাইম এক্সেকশন নিক্ষেপ করুন ...}
ianpojman

76

গুগল সংগ্রহের কাঠামো নাল চেকটি অর্জনের জন্য একটি ভাল এবং মার্জিত উপায় সরবরাহ করে।

লাইব্রেরি ক্লাসে এর মতো একটি পদ্ধতি রয়েছে:

static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}

এবং ব্যবহারটি হল (সাথে import static):

...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...

বা আপনার উদাহরণে:

checkNotNull(someobject).doCalc();

71
মিমি, পার্থক্য কী? p.getAge () কম ওভারহেড এবং একটি পরিষ্কার স্ট্যাক ট্রেস সহ একই এনপিই নিক্ষেপ করবে। আমি কী মিস করছি?
রহস্যময়

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

6
এটি এখন গুগল পেয়ারার অংশ।
স্টিভেন বেনিতেজ

32
আমার কাছে ওভার ইঞ্জিনিয়ারিংয়ের মতো গন্ধ আছে। কেবল জেভিএমকে একটি এনপিই নিক্ষেপ করতে দিন এবং এই জাঙ্কটি দিয়ে আপনার কোডটিকে বিশৃঙ্খলা না করে।
অ্যালেক্স ওয়ার্ডেন

5
আমি এটি পছন্দ করি এবং যুক্তিগুলির সুস্পষ্ট চেক সহ বেশিরভাগ পদ্ধতি এবং নির্মাতা খুলি; যদি কোনও ত্রুটি থাকে তবে পদ্ধতিগুলি সর্বদা প্রথম কয়েকটি লাইনে ব্যর্থ হয় এবং আমি এরকম কিছু না পেয়ে আপত্তিকর রেফারেন্সটি জানিgetThing().getItsThing().getOtherThing().wowEncapsulationIsBroken().setLol("hi");
Cory Kendall

75

কখনও কখনও, আপনার কাছে এমন পদ্ধতি রয়েছে যা এর পরামিতিগুলিতে কাজ করে যা একটি প্রতিসম ক্রিয়াকে সংজ্ঞায়িত করে:

a.f(b); <-> b.f(a);

যদি আপনি জানেন যে বি কখনই শূন্য হতে পারে না, আপনি কেবল এটি অদলবদল করতে পারেন। এটি সমান জন্য সবচেয়ে দরকারী: পরিবর্তে foo.equals("bar");আরও ভাল করতে "bar".equals(foo);


2
তবে আপনাকে ধরে equalsনিতে হবে (কোনও পদ্ধতি হতে পারে) সঠিকভাবে নাল পরিচালনা করবে। সত্যিই এই সমস্ত কাজটি করছে অন্য কারও কাছে দায়িত্ব (বা অন্য কোনও পদ্ধতি) প্রেরণ করা।
সুপ্রসন্ন

4
@ সুপিরিসি মূলত হ্যাঁ, তবে equals(বা যে কোনও পদ্ধতিতে) nullযেভাবেই হোক তা পরীক্ষা করতে হবে। বা স্পষ্টভাবে বলুন যে এটি না।
অ্যাঞ্জেলো ফুকস

74

নাল অবজেক্ট প্যাটার্নের পরিবর্তে - যার ব্যবহার রয়েছে - আপনি এমন পরিস্থিতিতে বিবেচনা করতে পারেন যেখানে নাল বস্তুটি একটি বাগ।

ব্যতিক্রম নিক্ষেপ করা হলে, স্ট্যাক ট্রেস পরীক্ষা করুন এবং বাগের মাধ্যমে কাজ করুন।


17
সমস্যাটি হ'ল সাধারণত নলপয়েন্টারএক্সসেপশনটি আপনার প্রসঙ্গটি আলগা করে দেয় না যা সূচিত করে যা ভেরিয়েবল নাল ছিল এবং আপনার বেশ কয়েকটি "।" - লাইনে অপারেশন থাকতে পারে। "If (foo == নাল) থ্রো করে নতুন রানটাইম এক্সেপশন (" foo == নাল ")" ব্যবহার করে আপনাকে স্পষ্টভাবে বলতে হবে যে কী ভুল ছিল, আপনার স্ট্যাক ট্রেসকে এটি ঠিক করার জন্য আরও বেশি মূল্য প্রদান করে।
থোরবজর্ন রাভন অ্যান্ডারসন

1
অ্যান্ডারসেনের সাথে - আমি জাভাটির ব্যতিক্রম সিস্টেমটি পছন্দ করে যা একটি চলকটির সাথে কাজ করা হচ্ছে তার নাম অন্তর্ভুক্ত করতে সক্ষম হব, যাতে নলপয়েন্টারএক্সেপশনগুলি কেবল ব্যতিক্রমের রেখাটিই নির্দেশ করে না, তবে ভেরিয়েবলের নামটিও প্রদর্শন করে। এটি অব্যক্ত সফ্টওয়্যারটিতে ঠিক কাজ করা উচিত।
fwielstra

আমি এখনও এটি কাজ করতে পরিচালিত করতে পারি না, তবে এটি ঠিক সেই সমস্যাটি সমাধান করার উদ্দেশ্যে।
ম্যাট্রিক্সফ্রাগ

সমস্যাটা কি? যথাযথ পর্যায়ে যেখানে এনপাই পর্যাপ্ত প্রসঙ্গ উপলব্ধ সেখানে ধরুন, প্রসঙ্গের তথ্যটি ফেলে দিন এবং ব্যতিক্রমটি পুনর্বিবেচনা করুন ... জাভা দিয়ে এটি এত সহজ।
ব্যবহারকারী 1050755

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

74

নাল কোনও 'সমস্যা' নয়। এটি একটি সম্পূর্ণ মডেলিং সরঞ্জাম সেটের একটি অবিচ্ছেদ্য অঙ্গ । সফ্টওয়্যারটির লক্ষ্য বিশ্বের জটিলতার মডেল করা এবং তার বোঝা বহন করে। নাল জাভা এবং এর মতো 'কোনও ডেটা নয়' বা 'অজানা' নির্দেশ করে । সুতরাং এই উদ্দেশ্যে নাল ব্যবহার করা উপযুক্ত। আমি 'নাল অবজেক্ট' প্যাটার্নটিকে পছন্দ করি না; আমি মনে করি এটি ' অভিভাবকদের কে রক্ষা করবে ' সমস্যা উত্থাপন করে ।
আপনি যদি আমাকে জিজ্ঞাসা করেন আমার বান্ধবীর নাম কি আমি আপনাকে বলব যে আমার কোনও বান্ধবী নেই। জাভা ভাষায় আমি নালার দিকে ফিরে আসব। একটি বিকল্প হতে পারে না এমন কিছু সমস্যা যা বোঝাতে পারে তার অর্থপূর্ণ ব্যতিক্রম ছোঁড়া (বা ডন 'নয়)

  1. একটি 'অজানা প্রশ্নের' জন্য 'অজানা উত্তর' দিন। (এটি ব্যবসার দৃষ্টিকোণ থেকে সঠিক যেখানে নাল-নিরাপদ থাকুন) ব্যবহারের আগে কোনও পদ্ধতির ভিতরে একবার নালীর পক্ষে যুক্তি যাচাই করা একাধিক কলারকে কল দেওয়ার আগে তাদের পরীক্ষা করতে বাধা দেয়।

    public Photo getPhotoOfThePerson(Person person) {
        if (person == null)
            return null;
        // Grabbing some resources or intensive calculation
        // using person object anyhow.
    }

    পূর্ববর্তী আমার ফটো লাইব্রেরি থেকে অস্তিত্বহীন বান্ধবীর কোনও ছবি না পাওয়ার জন্য স্বাভাবিক লজিক প্রবাহকে বাড়ে।

    getPhotoOfThePerson(me.getGirlfriend())

    এবং এটি নতুন আগত জাভা এপিআইয়ের সাথে ফিট করে (প্রত্যাশিত)

    getPhotoByName(me.getGirlfriend()?.getName())

    যদিও কোনও ব্যক্তির জন্য ডিবিতে সঞ্চিত ফটো না পাওয়া বরং এটি 'সাধারণ ব্যবসায়ের প্রবাহ', তবে আমি অন্য কয়েকটি ক্ষেত্রে নীচের মতো জোড়া ব্যবহার করতাম

    public static MyEnum parseMyEnum(String value); // throws IllegalArgumentException
    public static MyEnum parseMyEnumOrNull(String value);

    এবং টাইপ করতে ঘৃণা করবেন না <alt> + <shift> + <j>(Eclipse এ জাভাডোক উত্পন্ন) এবং আপনার জনসাধারণের API এর জন্য আরও তিনটি শব্দ লিখুন। যারা ডকুমেন্টেশন পড়েন না তাদের সবার জন্য এটি যথেষ্ট পরিমাণে বেশি হবে।

    /**
     * @return photo or null
     */

    অথবা

    /**
     * @return photo, never null
     */
  2. এটি বরং তাত্ত্বিক ক্ষেত্রে এবং বেশিরভাগ ক্ষেত্রে আপনার জাভা নাল নিরাপদ এপিআই পছন্দ করা উচিত (যদি এটি আরও 10 বছরে প্রকাশিত হয়) তবে NullPointerExceptionএটি একটি সাবক্লাস Exceptionসুতরাং এটি এমন একটি Throwableপরিস্থিতি যা একটি যুক্তিসঙ্গত অ্যাপ্লিকেশন ( জাভাদোক ) ধরতে চাইতে পারে এমন পরিস্থিতিতে নির্দেশ করে ! ব্যতিক্রম এবং পৃথক ত্রুটি পরিচালনার 'নিয়মিত' কোড থেকে কোড (প্রথম সবচেয়ে সুবিধা ব্যবহার করার জন্য জাভা এর নির্মাতাদের অনুযায়ী ) এটি উপযুক্ত আমার জন্য যেমন, ধরা NullPointerException

    public Photo getGirlfriendPhoto() {
        try {
            return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
        } catch (NullPointerException e) {
            return null;
        }
    }

    প্রশ্ন উঠতে পারে:

    প্র: যদি getPhotoDataSource()শূন্য ফিরে আসে?
    উ: এটি ব্যবসায়ের যুক্তি পর্যন্ত। আমি কোনও ফটো অ্যালবাম খুঁজে পেতে ব্যর্থ হলে আমি আপনাকে কোনও ফটো দেখাব না। অ্যাপকন্টেক্সট চালু না হলে কী হবে? এই পদ্ধতির ব্যবসায়ের যুক্তি এটির সাথে যুক্ত করে। যদি একই যুক্তিটি আরও কঠোর হওয়া উচিত তবে ব্যতিক্রম ছোঁড়া এটি ব্যবসায়ের যুক্তির অংশ এবং নালটির জন্য সুস্পষ্ট চেক ব্যবহার করা উচিত (কেস 3)। ভাল এখানে নতুন জাভা নাল-নিরাপদ এপিআই তড়কা নির্দিষ্ট করতে বেছে বেছে কি বুঝানো এবং কি পরোক্ষভাবে না সক্রিয়া করা ব্যর্থ-ফাস্ট প্রোগ্রামার ত্রুটি ক্ষেত্রে যাবে।

    প্র: রিডানড্যান্ট কোড কার্যকর করা যেতে পারে এবং অপ্রয়োজনীয় সংস্থান দখল করা যেতে পারে।
    উ: এটি সংঘটিত হতে পারে যদি getPhotoByName()কোনও ডাটাবেস সংযোগ খোলার চেষ্টা করা PreparedStatementহয়, শেষ পর্যন্ত কোনও ব্যক্তির নাম এসকিউএল প্যারামিটার হিসাবে তৈরি এবং ব্যবহার করে। একটি অজানা প্রশ্নের জন্য পদ্ধতির একটি অজানা উত্তর দেয় (কেস 1) এখানে কাজ করে। সংস্থানগুলি গ্রহণ করার আগে পদ্ধতিটির পরামিতিগুলি পরীক্ষা করা উচিত এবং প্রয়োজনে 'অজানা' ফলাফলটি ফিরিয়ে দেওয়া উচিত।

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

    পুনশ্চ. "নিয়মিত" কোড নীতি থেকে পৃথক ত্রুটি-পরিচালনা কোডটি কোথাও ব্যবহার করা যুক্তিসঙ্গত হিসাবে এই পদ্ধতির ব্যবহার যথাযথ হবে । পরবর্তী উদাহরণ বিবেচনা করুন:

    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        try {
            Result1 result1 = performSomeCalculation(predicate);
            Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
            Result3 result3 = performThirdCalculation(result2.getSomeProperty());
            Result4 result4 = performLastCalculation(result3.getSomeProperty());
            return result4.getSomeProperty();
        } catch (NullPointerException e) {
            return null;
        }
    }
    
    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        SomeValue result = null;
        if (predicate != null) {
            Result1 result1 = performSomeCalculation(predicate);
            if (result1 != null && result1.getSomeProperty() != null) {
                Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
                if (result2 != null && result2.getSomeProperty() != null) {
                    Result3 result3 = performThirdCalculation(result2.getSomeProperty());
                    if (result3 != null && result3.getSomeProperty() != null) {
                        Result4 result4 = performLastCalculation(result3.getSomeProperty());
                        if (result4 != null) {
                            result = result4.getSomeProperty();
                        }
                    }
                }
            }
        }
        return result;
    }

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

  3. ব্যবসায়ের যুক্তি কেবল তখনই প্রয়োগ করে যদি 'কোনও তথ্য নেই' জন্য পরীক্ষা করুন।

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person != null) {
            person.setPhoneNumber(phoneNumber);
            dataSource.updatePerson(person);
        } else {
            Person = new Person(personId);
            person.setPhoneNumber(phoneNumber);
            dataSource.insertPerson(person);
        }
    }

    এবং

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person == null)
            throw new SomeReasonableUserException("What are you thinking about ???");
        person.setPhoneNumber(phoneNumber);
        dataSource.updatePerson(person);
    }

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


6
ডিবাগ করা ধরা NullPointerExceptionএবং ফিরে আসা nullভয়ঙ্কর। আপনি পরে যাইহোক এনপিইয়ের সাথে শেষ করেছেন এবং মূলত শূন্যটি কী তা নির্ধারণ করা সত্যিই শক্ত।
আর্টব্রিস্টল

23
আমার সুনাম থাকলে আমি নামিয়ে ফেলতাম। শুধু নাল প্রয়োজনীয় নয়, এটি টাইপ সিস্টেমে একটি গর্ত। একটি তালিকায় একটি গাছ বরাদ্দ করা একটি ধরণের ত্রুটি কারণ গাছ প্রকারের তালিকার মান নয়; সেই একই যুক্তি অনুসারে, নাল নির্ধারণ করা একটি টাইপ ত্রুটি হওয়া উচিত কারণ নাল সেই ধরণের অবজেক্টের মান নয় বা সেই বিষয়ে কোনও কার্যকর টাইপ নয়। এমনকি যে ব্যক্তি নাল উদ্ভাবন করেছে তাকে এটিকে তার "বিলিয়ন ডলারের ভুল" হিসাবে বিবেচনা করে। "একটি মান যা টি বা টাইপের কোনও ধরণের মান হতে পারে" এর ধারণাটি তার নিজস্ব ধরণের এবং এটির (যেমন সম্ভবত <T> বা <চ্ছিক <T>) হিসাবে এটি উপস্থাপন করা উচিত।
ডোভাল

2
"সম্ভবত <T> বা <চ্ছিক <T>" হিসাবে আপনার এখনও কোড লিখতে হবে if (maybeNull.hasValue()) {...}তাই এর সাথে পার্থক্য কী if (maybeNull != null)) {...}?
মাইখ্যালো আদোমোভিচ

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

3
@ মাইখায়লো অ্যাডোমোভিচ: আপনার ক্ষেত্রে শূন্য হতে পারে এমন ক্ষেত্রে Maybe<T>বা এর সুবিধা নেই , তবে যেখানে এটি কখনই বাতিল হবে না। আপনার যদি এমন কোনও ধরণের থাকে যা স্পষ্টভাবে বোঝায় যে "এই মানটি নাল হতে পারে - সাবধানতার সাথে ব্যবহার করুন", এবং আপনি এই জাতীয় ধরণটি ধারাবাহিকভাবে ব্যবহার এবং ফিরিয়ে দেন, তবে যখনই আপনি আপনার কোডটিতে কোনও সরল পুরানো দেখতে পাচ্ছেন , আপনি ধরে নিতে পারেন যে এটি কখনই বাতিল নয়। (কোর্স, সংকলক দ্বারা প্রয়োগযোগ্য যদি এটি অনেক বেশি কার্যকর হয়))Optional<T>TT
সিএইচও

71

জাভা 7 এর একটি নতুন java.util.Objectsইউটিলিটি ক্লাস রয়েছে যার উপর একটি requireNonNull()পদ্ধতি রয়েছে। এর সমস্ত NullPointerExceptionযুক্তি যদি নালার হয় তবে এটি কিছু ফেলে দেয় তবে কোডটি কিছুটা সাফ করে। উদাহরণ:

Objects.requireNonNull(someObject);
someObject.doCalc();

কনস্ট্রাক্টরের একটি অ্যাসাইনমেন্টের ঠিক আগে পরীক্ষাটি পরীক্ষা করার জন্য পদ্ধতিটি সবচেয়ে কার্যকর , যেখানে এটির প্রতিটি ব্যবহারের ফলে কোডের তিনটি লাইন সংরক্ষণ করা যায়:

Parent(Child child) {
   if (child == null) {
      throw new NullPointerException("child");
   }
   this.child = child;
}

হয়ে

Parent(Child child) {
   this.child = Objects.requireNonNull(child, "child");
}

9
প্রকৃতপক্ষে, আপনার উদাহরণটি কোডটি ব্লাট গঠন করে: প্রথম লাইনটি অতিমাত্রায় হয় কারণ এনপিই দ্বিতীয় লাইনে নিক্ষিপ্ত হয়। ;-)
ব্যবহারকারী 1050755

1
সত্য। একটি ভাল উদাহরণ যদি দ্বিতীয় লাইন ছিল হবে doCalc(someObject)
স্টুয়ার্ট

নির্ভর করে। আপনি যদি ডক্যাল্যাক () এর লেখক হন তবে আমি চেকটি সেই পদ্ধতির শরীরে রাখার পরামর্শ দিই (যদি সম্ভব হয়)। এবং তারপরে আপনি সম্ভবত কিছু অবজেক্ট.সোমমথোড () কল করবেন যেখানে আবার নাল পরীক্ষা করার দরকার নেই। :-)
ব্যবহারকারী 1050755

ঠিক আছে, আপনি যদি এর লেখক না হন doCalc()এবং শূন্য করার সময় এটি তাত্ক্ষণিকভাবে এনপিই নিক্ষেপ করে না, আপনার নাল পরীক্ষা করে নিজেই এনপিই নিক্ষেপ করতে হবে। এটা কি Objects.requireNonNull()জন্য।
স্টুয়ার্ট

7
এটি কেবল কোড ফোলা নয়। পার্শ্ব প্রতিক্রিয়া সৃষ্টি করে বা সময় / স্থান ব্যবহার করে এমন কোনও পদ্ধতির মাধ্যমে অর্ধেকের চেয়ে সামনের দিকে চেয়ে ভাল।
রব গ্রান্ট

51

শেষ পর্যন্ত, এই সমস্যাটিকে সম্পূর্ণ সমাধান করার একমাত্র উপায় হ'ল ভিন্ন প্রোগ্রামিং ভাষা ব্যবহার করে:

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

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

4
আমি নিস এর সাথে পরিচিত নই, তবে কোটলিন একই ধারণা প্রয়োগ করে, ভাষার টাইপ সিস্টেমে নমনীয় এবং নাল ধরণের থাকে। অপশনাল বা নাল অবজেক্ট প্যাটার্নের চেয়ে অনেক বেশি সংক্ষিপ্ত।
mtsahakis

38

সত্যিই জাভাতে সাধারণ "সমস্যা"।

প্রথমত, এই সম্পর্কে আমার মতামত:

আমি বিবেচনা করি যে কোনও কিছু "খাওয়া" খারাপ, যখন NULL পাস হয় যেখানে NULL একটি বৈধ মান নয়। যদি আপনি কোনও ধরণের ত্রুটিযুক্ত পদ্ধতিটি থেকে বেরিয়ে না আসেন তবে এর অর্থ আপনার পদ্ধতিতে কোনও কিছুই ভুল হয়নি যা সত্য নয়। তারপরে আপনি সম্ভবত এই ক্ষেত্রে নাল ফিরে আসবেন, এবং প্রাপ্ত পদ্ধতিতে আপনি আবার নাল পরীক্ষা করে দেখুন, এবং এটি কখনও শেষ হয় না এবং আপনি "if! = নাল", ইত্যাদি দিয়ে শেষ করেন ..

সুতরাং, আইএমএইচও, নাল অবশ্যই একটি গুরুতর ত্রুটি হতে হবে যা আরও কার্যকরভাবে আটকাতে পারে (যা নাল একটি বৈধ মান নয়)।

আমি এই সমস্যার সমাধান করার উপায়টি হ'ল:

প্রথমত, আমি এই সম্মেলনটি অনুসরণ করি:

  1. সমস্ত পাবলিক পদ্ধতি / এপিআই সর্বদা শূন্যের জন্য তার যুক্তিগুলি পরীক্ষা করে
  2. সমস্ত ব্যক্তিগত পদ্ধতিগুলি নিয়ন্ত্রিত পদ্ধতি হওয়ায় নালটি যাচাই করে না (কেবল উপরের দিকে পরিচালিত না হলে নালপয়েন্টার ব্যতিক্রম দিয়ে মারা যেতে দিন)
  3. নাল পরীক্ষা করে না এমন একমাত্র অন্যান্য পদ্ধতি হ'ল ইউটিলিটি পদ্ধতি। এগুলি সর্বজনীন, তবে আপনি যদি কোনও কারণে তাদের কল করেন তবে আপনি কী পরামিতিগুলি পাস করবেন তা আপনি জানেন। এটি জল সরবরাহ না করে কেটলিতে জল ফুটানোর চেষ্টা করার মতো ...

এবং পরিশেষে, কোডটিতে, সর্বজনীন পদ্ধতির প্রথম লাইনটি এভাবে চলে:

ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();

নোট করুন যে অ্যাডপ্যারাম () নিজেই ফিরে আসে, যাতে আপনি চেক করতে আরও পরামিতি যুক্ত করতে পারেন।

প্যারামিটারগুলির কোনও শূন্য হলে পদ্ধতিটি validate()চেক করা নিক্ষেপ করবে ValidationException(চেক বা চেক করা না হওয়া আরও একটি ডিজাইন / স্বাদ সমস্যা, তবে আমার ValidationExceptionপরীক্ষা করা হয়েছে)।

void validate() throws ValidationException;

বার্তাটিতে নীচের পাঠ্য থাকবে যদি উদাহরণস্বরূপ, "পরিকল্পনা" শূন্য থাকে:

" প্যারামিটারের জন্য অবৈধ আর্গুমেন্টের মান শূন্য হয় [পরিকল্পনা] "

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

এবং হ্যাঁ, আমরা জানি যে এই লাইনটি পেরিয়ে আমরা আর কোনও নাল মানের মুখোমুখি হব না তাই আমরা নিরাপদে objects অবজেক্টগুলিতে পদ্ধতিগুলি প্রার্থনা করব।

এইভাবে, কোডটি পরিষ্কার, সহজ রক্ষণাবেক্ষণযোগ্য এবং পঠনযোগ্য।


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

35

এই প্রশ্নটি জিজ্ঞাসা করে যে আপনি ত্রুটি পরিচালনার কৌশলগুলিতে আগ্রহী হতে পারেন points আপনার দলের স্থপতিদের কীভাবে ত্রুটিগুলি কাজ করা যায় তা স্থির করা উচিত। এই কাজ করার বিভিন্ন উপায় আছে:

  1. ব্যতিক্রমগুলি লুপ্ত হওয়ার অনুমতি দিন - তাদেরকে 'মূল লুপ' বা অন্য কোনও পরিচালনার রুটিনে ধরুন।

    • ত্রুটির অবস্থার জন্য পরীক্ষা করুন এবং এগুলি যথাযথভাবে পরিচালনা করুন

অবশ্যই অ্যাস্পেক্ট ওরিয়েন্টেড প্রোগ্রামিংটি একবার দেখে নিন - তাদের if( o == null ) handleNull()আপনার বাইকোডে প্রবেশ করার ঝরঝরে উপায় রয়েছে ।


35

ব্যবহারের পাশাপাশি আপনি assertনিম্নলিখিতটি ব্যবহার করতে পারেন:

if (someobject == null) {
    // Handle null here then move on.
}

এটি এর থেকে কিছুটা ভাল:

if (someobject != null) {
    .....
    .....



    .....
}

2
মাঃ কেন? দয়া করে
কোনওরকম

9
@ মুদু একটি সাধারণ নিয়ম হিসাবে, আমি যদি একটি "নেতিবাচক" বর্ণনার চেয়ে আরও "ইতিবাচক" বিবৃতি হিসাবে একটি বিবৃতিতে অভিব্যক্তিটি পছন্দ করি। সুতরাং যদি আমি দেখেছি তবে আমি if (!something) { x(); } else { y(); }এটির মতো চুল্লী নেওয়ার প্রবণতা পোষণ করব if (something) { y(); } else { x(); }(যদিও কেউ যুক্তি দিতে পারে যে != nullএটিই ইতিবাচক বিকল্প ...)। তবে আরও গুরুত্বপূর্ণ, কোডের গুরুত্বপূর্ণ অংশটি {}এস এর ভিতরে আবৃত হয় না এবং বেশিরভাগ পদ্ধতির জন্য আপনার কাছে এক স্তর কম ইনডেন্টেশন থাকে। আমি জানি না যে এটি ফাস্টকোডিজেভার যুক্তিযুক্ত ছিল কিনা তবে তা আমার হবে।
ম্যাট্রিক্সফ্রোগ

1
এটি আমিও একইভাবে ঝোঁক করছি .. কোডটি আমার মতামতটিতে পরিষ্কার রাখে।
Koray Tugay

34

শুধু কখনও নাল ব্যবহার করবেন না। এটি অনুমতি দেয় না।

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

একবার আমি এই অনুশীলনটি অবলম্বন করার পরে, আমি লক্ষ্য করেছি যে সমস্যাগুলি তাদের সংশোধন করেছে বলে মনে হচ্ছে। আপনি ঠিক আগে দুর্ঘটনাক্রমে বিকাশ প্রক্রিয়াতে জিনিসগুলি ধরতে পারবেন এবং বুঝতে পারেন যে আপনার একটি দুর্বল জায়গা ছিল .. এবং আরও গুরুত্বপূর্ণ এটি .. এটি বিভিন্ন মডিউলগুলির উদ্বেগকে সজ্জিত করতে সহায়তা করে, বিভিন্ন মডিউল একে অপরকে 'বিশ্বাস' করতে পারে, এবং আর কোনও জঞ্জাল নয় if = null elseকনস্ট্রাক্টসের সাথে কোড !

এটি প্রতিরক্ষামূলক প্রোগ্রামিং এবং এর ফলে দীর্ঘ মেয়াদে অনেক ক্লিনার কোড আসে। সর্বদা ডেটা স্যানিটাইজ করুন, উদাহরণস্বরূপ এখানে কঠোর মান প্রয়োগ করে সমস্যাগুলি চলে যায়।

class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}

চুক্তিগুলি মিনি-ইউনিট পরীক্ষার মতো যা সর্বদা চলমান থাকে, এমনকি উত্পাদনেও, এবং যখন জিনিসগুলি ব্যর্থ হয়, তখন আপনি কেন জানবেন, এলোমেলো এনপিইর পরিবর্তে আপনাকে কোনওভাবে খুঁজে বের করতে হবে।


এটিকে কেন হ্রাস করা হবে? আমার অভিজ্ঞতায়, এটি অন্যান্য পদ্ধতির তুলনায় অনেক উন্নত, কেন তা জানতে পছন্দ করবেন
ianpojman

আমি সম্মত, এই পদ্ধতির নকল সম্পর্কিত সমস্যাগুলি প্রতিরোধ করে, যেকোন জায়গায় স্পেকলিং কোড নাল চেকগুলি সমাধান করার পরিবর্তে ull
ক্রিসব্লম

7
এই পদ্ধতির সমস্যাটি হ'ল যদি নামটি কখনই সেট না করা হয় তবে এর মান "<অজ্ঞাত>" থাকে যা একটি সেট মানের মতো আচরণ করে। এখন বলি যে নামটি কখনই সেট করা হয়নি (অজানা), আমাকে যাচাই করা দরকার, বিশেষ মান "<অজ্ঞাত>" এর সাথে আমাকে স্ট্রিং তুলনা করতে হবে।
স্টিভ কুও

1
সত্য ভাল পয়েন্ট স্টিভ। আমি প্রায়শই যা করি তার মানটি একটি ধ্রুবক হিসাবে থাকে, যেমন পাবলিক স্ট্যাটিক ফাইনাল স্ট্রিং ইউএনএসইটি = "__ আনসেট" ... প্রাইভেট স্ট্রিং ফিল্ড = ইউএনএসইটি ... তারপরে প্রাইভেট বুলিয়ান ইসসেট () {রিটার্ন ইউএনএসইটি.ইকিলস (ফিল্ড); }
আয়নপুজমান

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

31

গুয়ারা একটি অত্যন্ত দরকারী মূল লাইব্রেরি, নালাগুলি এড়ানোর জন্য একটি দুর্দান্ত এবং দরকারী API রয়েছে has আমি UseAndAvoidingNullExplained খুব সহায়ক বলে মনে করি।

উইকিতে যেমন ব্যাখ্যা করা হয়েছে:

Optional<T>হ'ল একটি নাল-টিযুক্ত রেফারেন্সকে নন-নাল মান দিয়ে প্রতিস্থাপনের একটি উপায়। একটি ptionচ্ছিক হয় হয় একটি নন-টি-টি রেফারেন্স থাকতে পারে (যার ক্ষেত্রে আমরা উল্লেখ করি যে রেফারেন্সটি "উপস্থিত"), বা এতে কিছু নাও থাকতে পারে (এই ক্ষেত্রে আমরা উল্লেখ করি যে রেফারেন্সটি "অনুপস্থিত")। এটি কখনও "নালকে ধারণ করে" বলে বলা হয় না।

ব্যবহার:

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5

@ কোডি গুল্ডনার রাইট, কোডি। আরও প্রসঙ্গ দেওয়ার জন্য আমি লিঙ্ক থেকে একটি প্রাসঙ্গিক উদ্ধৃতি সরবরাহ করেছি।
মুরাত দেরিয়া enzen

25

এটি প্রতিটি জাভা বিকাশকারীদের পক্ষে খুব সাধারণ সমস্যা। তাই বিশৃঙ্খল কোড ছাড়াই এই সমস্যাগুলি সমাধান করার জন্য জাভা 8-তে সরকারী সমর্থন রয়েছে।

জাভা 8 চালু করেছে java.util.Optional<T>। এটি এমন একটি ধারক যা একটি নন-মান বা না ধরে রাখতে পারে। জাভা 8 কোনও বস্তুর হ্যান্ডেল করার জন্য একটি নিরাপদ উপায় দিয়েছে যার মান কিছু ক্ষেত্রে শূন্য হতে পারে। এটি হাস্কেল এবং স্কালার ধারণাগুলি থেকে অনুপ্রাণিত ।

সংক্ষেপে, valueচ্ছিক ক্লাসে যেখানে মান উপস্থিত বা অনুপস্থিত সেখানে কেস স্পষ্টভাবে মোকাবেলা করার পদ্ধতি অন্তর্ভুক্ত করে। তবে নাল রেফারেন্সের তুলনায় সুবিধাটি হ'ল ptionচ্ছিক <টি> শ্রেণি মানটি উপস্থিত না থাকলে আপনাকে কেসটি সম্পর্কে ভাবতে বাধ্য করে। ফলস্বরূপ, আপনি অনিচ্ছাকৃত নাল পয়েন্টার ব্যতিক্রমগুলি প্রতিরোধ করতে পারেন।

উপরের উদাহরণে আমাদের একটি হোম সার্ভিস কারখানা রয়েছে যা ঘরে উপলব্ধ একাধিক অ্যাপ্লিকেশনগুলিতে একটি হ্যান্ডেল ফিরিয়ে দেয়। তবে এই পরিষেবাগুলি উপলভ্য / কার্যকরী হতে পারে বা নাও থাকতে পারে; এর অর্থ এটি একটি নালপয়েন্টার এক্সসেপশন এর ফলে আসতে পারে। ifকোনও পরিষেবা ব্যবহারের আগে নাল শর্ত যুক্ত করার পরিবর্তে, এটি এটিকে ptionচ্ছিক <সার্ভিস> এ মুড়িয়ে দিন।

বিকল্পের মোড়ক <T>

কারখানা থেকে কোনও পরিষেবার রেফারেন্স পেতে একটি পদ্ধতি বিবেচনা করা যাক। পরিষেবার রেফারেন্সটি ফিরিয়ে দেওয়ার পরিবর্তে, এটি ptionচ্ছিক দিয়ে মোড়ানো করুন। এটি এপিআই ব্যবহারকারীকে জানতে দেয় যে প্রত্যাবর্তিত পরিষেবাটি উপলভ্য / কার্যকরী হতে পারে বা ডিফেন্সিয়ালি ব্যবহার করতে পারে

public Optional<Service> getRefrigertorControl() {
      Service s = new  RefrigeratorService();
       //...
      return Optional.ofNullable(s);
   }

যেমন আপনি দেখুন Optional.ofNullable()রেফারেন্স মোড়ানো একটি সহজ উপায় সরবরাহ করে। Optional.empty()& চ্ছিক রেফারেন্স পেতে অন্য উপায় আছে, হয় & হয় Optional.of()। একটি যথাক্রমে নাল পুনরায় সংঘবদ্ধ করার পরিবর্তে একটি খালি বস্তু ফেরত দেওয়ার জন্য এবং অন্যটি যথাক্রমে একটি নন-অ্যালবামযোগ্য বস্তু মোড়ানোর জন্য।

ঠিক কীভাবে কোনও নাল চিকিত্সা এড়াতে সহায়তা করে?

একবার আপনি কোনও রেফারেন্স অবজেক্ট মোড়ানো হয়ে গেলে, PEচ্ছিক এনপিই ছাড়াই মোড়ানো রেফারেন্সে পদ্ধতিগুলি আহ্বান করতে অনেক দরকারী পদ্ধতি সরবরাহ করে।

Optional ref = homeServices.getRefrigertorControl();
ref.ifPresent(HomeServices::switchItOn);

বিকল্প if অন্যথায়, এটি কিছুই করে না।

@FunctionalInterface
public interface Consumer<T>

এমন একটি অপারেশনকে উপস্থাপন করে যা একটি একক ইনপুট আর্গুমেন্ট গ্রহণ করে এবং কোনও ফল দেয় না। অন্যান্য কার্যকরী ইন্টারফেসের বিপরীতে, গ্রাহকরা পার্শ্ব প্রতিক্রিয়াগুলির মাধ্যমে পরিচালিত হবে বলে আশা করা হচ্ছে। এটি এত পরিষ্কার এবং সহজে বোঝা যায়। উপরের কোড উদাহরণে, HomeService.switchOn(Service)invচ্ছিক হোল্ডিং রেফারেন্স অকার্যকর হলে অনুরোধ করা হবে।

আমরা নাল কন্ডিশনটি যাচাই করার জন্য প্রায়শই টার্নারি অপারেটরটি ব্যবহার করি এবং একটি বিকল্প মান বা ডিফল্ট মান ফিরে পাই। Checkingচ্ছিক শূন্যতা পরীক্ষা না করে একই শর্তটি পরিচালনা করার জন্য অন্য উপায় সরবরাহ করে। Ptionচ্ছিকের একটি নাল মান থাকলে ptionচ্ছিক.অরএলস (ডিফল্ট ওবিজে) ডিফল্ট ওবজে ফেরত দেয়। আসুন এটি আমাদের নমুনা কোডটিতে ব্যবহার করুন:

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

এখন HomeServices.get () একই কাজ করে তবে আরও ভাল উপায়ে। এটি সার্ভিসটি ইতিমধ্যে চালু করা হয়নি কিনা তা পরীক্ষা করে। যদি তা হয় তবে একইটি ফেরত দিন বা একটি নতুন নতুন পরিষেবা তৈরি করুন। Ptionচ্ছিক <T>। বা এলিজ (টি) একটি ডিফল্ট মান ফিরে পেতে সহায়তা করে।

অবশেষে, এখানে আমাদের এনপিই পাশাপাশি নাল চেক-মুক্ত কোডটি রয়েছে:

import java.util.Optional;
public class HomeServices {
    private static final int NOW = 0;
    private static Optional<HomeServices> service;

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

public Optional<Service> getRefrigertorControl() {
    Service s = new  RefrigeratorService();
    //...
    return Optional.ofNullable(s);
}

public static void main(String[] args) {
    /* Get Home Services handle */
    Optional<HomeServices> homeServices = HomeServices.get();
    if(homeServices != null) {
        Optional<Service> refrigertorControl = homeServices.get().getRefrigertorControl();
        refrigertorControl.ifPresent(HomeServices::switchItOn);
    }
}

public static void switchItOn(Service s){
         //...
    }
}

সম্পূর্ণ পোস্টটি এনপিই পাশাপাশি নুল চেক-ফ্রি কোড… সত্যই?


উপরের কোডে একটি নাল চেক রয়েছে - if(homeServices != null) {যা এতে পরিবর্তন করা যেতে পারে homeServices.ifPresent(h -> //action);
কৃষাপ্রকাশ

23

আমি নাট প্রাইসের নিবন্ধগুলি পছন্দ করি। লিঙ্কগুলি এখানে:

নিবন্ধগুলিতে একটি জাভা মেইন টাইপের জন্য গিট সংগ্রহস্থলের একটি লিঙ্কও রয়েছে যা আমি আকর্ষণীয় বলে মনে করি, তবে আমি মনে করি না এটি একা চেকিং কোড ব্লাটকে হ্রাস করতে পারে। ইন্টারনেটে কিছু গবেষণা করার পরে, আমি মনে করি ! = নাল কোড ব্লাট প্রধানত সাবধানতার সাথে ডিজাইনের মাধ্যমে হ্রাস পেতে পারে।


মাইকেল ফেদারস
ivan.aguirre

21

আমি চেষ্টা করেছি NullObjectPatternতবে আমার পক্ষে সবসময় যাওয়ার সবচেয়ে ভাল উপায় নয়। কিছু সময় আছে যখন "কোনও ক্রিয়া না" প্রশ্রয় দেওয়া হয় না।

NullPointerExceptionএকটি হল রানটাইম ব্যতিক্রম মানে এটা ডেভেলপারদের দোষ এবং যথেষ্ট অভিজ্ঞতার সঙ্গে বলা হয়েছে যে সব আপনি ঠিক যেখানে ত্রুটি।

এখন উত্তর:

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

অবশ্যই, পরামর্শটি বোঝার এবং এই পরামর্শটি প্রয়োগ করার সর্বোত্তম উপায়।

বাইট!


19

সম্ভবত জাভা 8 বা আরও ভাল বিকল্পের জন্য Optionalক্লাসটি ব্যবহার করা ।

Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);

এটি সম্ভাব্য নাল মানগুলির দীর্ঘ চেইনের জন্য বিশেষত কার্যকর hand উদাহরণ:

Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());

নাল ব্যতিক্রম কীভাবে ফেলবেন তার উদাহরণ:

Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);

জাভা 7 Objects.requireNonNullপদ্ধতিটি চালু করেছিল যা কোনও শালীনতার জন্য পরীক্ষা করা উচিত যখন কার্যকর হতে পারে। উদাহরণ:

String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();

17

আমি কি আরও সাধারণভাবে উত্তর দিতে পারি!

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

সুতরাং এর মধ্যে কোনও পার্থক্য নেই:

if(object == null){
   //you called my method badly!

}

অথবা

if(str.length() == 0){
   //you called my method badly again!
}

তারা উভয়ই নিশ্চিত করতে চায় যে আমরা অন্য কোনও কার্য সম্পাদনের আগে বৈধ পরামিতি পেয়েছি।

অন্য কয়েকটি উত্তরে যেমন উল্লেখ করা হয়েছে, উপরের সমস্যাগুলি এড়ানোর জন্য আপনি চুক্তি অনুসারে ডিজাইনটি অনুসরণ করতে পারেন । দয়া করে http://en.wikedia.org/wiki/Design_by_contract দেখুন

জাভাতে এই প্যাটার্নটি বাস্তবায়নের জন্য, আপনি জাভ্যাক্স.অনোটেশন.নোটনল এর মতো মূল জাভা টিকা ব্যবহার করতে পারেন বা হাইবারনেট ভ্যালিডেটরের মতো আরও পরিশীলিত গ্রন্থাগার ব্যবহার করতে পারেন

মাত্র একটি নমুনা:

getCustomerAccounts(@NotEmpty String customerId,@Size(min = 1) String accountType)

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

আপনি আরও একধাপ এগিয়ে যেতে পারেন এবং নিশ্চিত করতে পারেন যে আপনার আবেদনে কেবল বৈধ পোজো তৈরি হতে পারে। (হাইবারনেট ভ্যালিডেটর সাইট থেকে নমুনা)

public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}

javaxসংজ্ঞা অনুসারে এটি "মূল জাভা" নয়।
টমাস

17

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

বাস্তবে যদি কোনও পদ্ধতি থেকে ফিরে আসা কোনও জিনিস বাতিল হয়ে যায় এবং কলিং কোডের উপর সিদ্ধান্ত নিতে হয়, এমন একটি পূর্ববর্তী কল থাকা উচিত যা রাষ্ট্রকে নিশ্চিত করে।

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

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

অযৌক্তিক ফলাফল এড়ানোর জন্য এই জাতীয় কেস বিবেচনা করা মূল্যবান।


"হ্যাশব্যাকগ্রাউন্ড ()" এর সমাধানটির একটি অপূর্ণতা রয়েছে - এটি থ্রেড-নিরাপদ নয়। যদি আপনার একটির পরিবর্তে দুটি পদ্ধতি কল করতে হয় তবে আপনাকে বহু ধারাবাহিক পরিবেশে পুরো ক্রমটি সিঙ্ক্রোনাইজ করতে হবে।
pkalinow

@ পকালিনো আপনি কেবল একটি সমাধানের উদাহরণ তৈরি করেছেন যে এই সমাধানটির কোনও অসুবিধা রয়েছে। কোডটি যদি মাল্টিথ্রেডেড অ্যাপ্লিকেশনটিতে চালিত না করে বোঝানো হয় তবে কোনও অসুবিধা নেই। আমি আপনাকে সম্ভবত আপনার 90% কোড রাখতে পারি যা থ্রেড নিরাপদ নয়। আমরা এখানে কোডের এই দিকটি নিয়ে কথা বলছি না, আমরা ডিজাইনের ধরণ সম্পর্কে বলছি। এবং মাল্টিথ্রেডিং নিজেই একটি বিষয়।
luke1985

অবশ্যই একক থ্রেড অ্যাপ্লিকেশনটিতে এটি কোনও সমস্যা নয়। আমি সেই মন্তব্যটি দিয়েছি কারণ মাঝে মাঝে এটি একটি সমস্যা হয়।
pkalinow

@ পকলিনো আপনি যদি এই বিষয়টিকে ঘনিষ্ঠভাবে অধ্যয়ন করেন তবে আপনি দেখতে পাবেন নাল অবজেক্ট ডিজাইনের ধরণটি মাল্টিথ্রেডিং সমস্যা সমাধান করবে না। সুতরাং এটি অপ্রাসঙ্গিক। এবং সত্যি কথা বলতে, আমি এমন জায়গা খুঁজে পেয়েছি যেখানে এই প্যাটার্নটি সুন্দরভাবে ফিট করে, তাই আমার আসল উত্তরটি আসলে কিছুটা ভুল।
luke1985

16
  1. ভেরিয়েবলগুলি কখনই শূন্য করতে শুরু করবেন না।
  2. যদি (1) সম্ভব না হয়, সমস্ত সংগ্রহ এবং অ্যারেগুলি খালি সংগ্রহ / অ্যারেতে শুরু করুন।

এটি আপনার নিজের কোডে করা এবং আপনি এড়াতে পারবেন! = নাল চেক।

নাল চেকগুলির বেশিরভাগ সময় সংগ্রহ বা অ্যারেতে লুপগুলি রক্ষা করা মনে হয়, তাই কেবল খালি এটি আরম্ভ করুন, আপনার কোনও নাল চেকের প্রয়োজন হবে না।

// Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}

এটিতে একটি ক্ষুদ্র ওভারহেড রয়েছে তবে এটি ক্লিনার কোড এবং কম নালপয়েন্টারএক্সবেশনগুলির জন্য এটি মূল্যবান।



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

15

এটি বেশিরভাগ বিকাশকারীদের ক্ষেত্রে সবচেয়ে সাধারণ ত্রুটি।

আমাদের এটি পরিচালনা করার অনেকগুলি উপায় রয়েছে have

পন্থা 1:

org.apache.commons.lang.Validate //using apache framework

নোট নয় (অবজেক্ট অবজেক্ট, স্ট্রিং মেসেজ)

পদ্ধতির 2:

if(someObject!=null){ // simply checking against null
}

পদ্ধতির 3:

@isNull @Nullable  // using annotation based validation

পদ্ধতির 4:

// by writing static method and calling it across whereever we needed to check the validation

static <T> T isNull(someObject e){  
   if(e == null){
      throw new NullPointerException();
   }
   return e;
}

বিজ্ঞাপন. ৪. এটি খুব কার্যকর নয় - আপনি যখন কোনও পয়েন্টারটি শূন্য হয় কিনা তা পরীক্ষা করেন, আপনি সম্ভবত এটিতে কোনও পদ্ধতিতে কল করতে চান। নাল পদ্ধতিতে কল করা আপনাকে একই আচরণ দেয় - নালপয়েন্টারএক্সেপশন।
pkalinow

11
public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}

2
এই পদ্ধতিতে কী সমস্যা হয়েছে, আমি মনে করি @ ক্লিটস্টার যদি এটি বাতিল হয় তবে এটি একটি ডিফল্ট মান দিতে চায় যা বোঝা যায়।
সাওয়ের

1
অ্যাপাচি কমন্স-ল্যাংয়ে এমন পদ্ধতি রয়েছে ObjectUtils.defaultIfNull()। আরও একটি সাধারণ রয়েছে: ObjectUtils.firstNonNull()যা একটি হ্রাসকারী কৌশল বাস্তবায়নের জন্য ব্যবহার করা যেতে পারে:firstNonNull(bestChoice, secondBest, thirdBest, fallBack);
আইভেন্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.