জাভা দৃsert় কীওয়ার্ডটি কী করে এবং কখন এটি ব্যবহার করা উচিত?


601

দৃser়তার মূল ভূমিকা বোঝার জন্য কিছু বাস্তব জীবনের উদাহরণ কী কী?


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

35
@ যিশাই: "আপনাকে ভাবতে হবে ... দাবি বন্ধ করা হয়েছে" আপনার যদি এটি করা দরকার হয় তবে আপনি এটি ভুল করছেন। "দাবীগুলি সীমিত ব্যবহারের একটি অকাল অপ্টিমাইজেশন" " এটি রেলপথ থেকে প্রায় দূরে। এখানে সূর্যের বিষয়টি গ্রহণ করুন: " জাভা টেকনোলজিতে
দৃser়তা

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

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

4
@ ডেভিডটনহোফার ডেভিড, আমি মনে করি আপনার দৃ your়তার প্রতি ভালবাসা একটি নির্দিষ্ট ধরণের প্রোগ্রামিংয়ের জন্য যা আপনি ছেলেরা করছেন, আমার ক্ষেত্রে যা ওয়েব অ্যাপ্লিকেশনগুলির সাথে কাজ করে যে কোনও কারণে প্রোগ্রাম থেকে বেরিয়ে আসার ক্ষেত্রে এটি সবচেয়ে বড় কিছু নয় - আমার ব্যক্তিগতভাবে কখনও হয়নি ইউনিট / ইন্টিগ্রেটেড টেস্টিং
বাদে অন্যরকম দৃ used

উত্তর:


426

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

একটি উদাহরণ:

public Foo acquireFoo(int id) {
  Foo result = null;
  if (id > 50) {
    result = fooService.read(id);
  } else {
    result = new Foo(id);
  }
  assert result != null;

  return result;
}

71
আসলে, ওরাকল আপনাকে assertপাবলিক মেথড প্যারামিটারগুলি পরীক্ষা করার জন্য ( ডকস.ওরাকল . com / javase / 1.4.2 / docs / guide / lang / assert.html ) পরীক্ষা না করতে বলে । Exceptionএটি প্রোগ্রাম হত্যা করার পরিবর্তে একটি নিক্ষেপ করা উচিত ।
এসজেউন 76

10
তবে আপনি কেন তাদের উপস্থিতি তা ব্যাখ্যা করেন না। আপনি যদি () পরীক্ষা করে ব্যতিক্রম ছুঁড়ে ফেলতে পারেন না কেন?
এল ম্যাক

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

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

8
This convention is unaffected by the addition of the assert construct. Do not use assertions to check the parameters of a public method. An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError. docs.oracle.com/javase/8/docs/technotes/guides/language/…
বখশি

325

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

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

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

// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
  return a + b;
}

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

// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
    assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
  final int result = a + b;
    assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
  return result;
}

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

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

এটি তবুও বাগ-মুক্ত কোডের কোনও গ্যারান্টি নয়, তবে এটি সাধারণ প্রোগ্রামের চেয়ে অনেক বেশি কাছে।


29
আমি এই উদাহরণটি বেছে নিয়েছি কারণ এটি আপাতদৃষ্টিতে বাগ-মুক্ত কোডে লুকিয়ে থাকা বাগগুলি উপস্থাপন করে। এটি যদি অন্য কারও উপস্থার সাথে মিলে যায় তবে তাদের মনেও একই ধারণা ছিল। ;)
TwoThe

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

5
এই সাধারণ ক্ষেত্রে প্রয়োজনীয়: না, তবে ডিবিসি নির্ধারণ করে যে প্রতিটি ফলাফল অবশ্যই পরীক্ষা করা উচিত। কল্পনা করুন যে কেউ এখন সেই ফাংশনটিকে আরও জটিল কিছুতে পরিবর্তন করে, তারপরে তাকে পোস্ট-চেকটিও মানিয়ে নিতে হবে, এবং তারপরে হঠাৎ এটি কার্যকর হয়ে ওঠে।
TwoThe

4
এটি পুনরুত্থিত করার জন্য দুঃখিত, তবে আমার একটি নির্দিষ্ট প্রশ্ন আছে। @ দু'একটি কী করেছে এবং new IllegalArgumentExceptionবার্তাটি দিয়ে কেবল একটি নিক্ষেপ করা দৃsert় ব্যবহারের পরিবর্তে কী পার্থক্য রয়েছে ? আমি বলতে চাইছি, অন্য throwsকোনও পদ্ধতিতে এই ব্যতিক্রমটি পরিচালনা করার জন্য পদ্ধতি ঘোষণা এবং কোডে ওপেন করা উচিত। কেন assertনতুন ব্যতিক্রম নিক্ষেপ ইনসেটেড? বা কেন একটি ifপরিবর্তে না assert? সত্যিই এটি পাওয়া যায় না :(
ব্লুয়ারইভার

14
-1: ওভারফ্লো পরীক্ষা করার জন্য জোর দেওয়া যদি aনেতিবাচক হতে পারে তবে ভুল । দ্বিতীয় দৃ়তা অকেজো; ইনট মানগুলির জন্য, এটি সর্বদা ক্ষেত্রে + বি - বি == এ ক্ষেত্রে হয়। কম্পিউটারটি মৌলিকভাবে ভেঙে গেলে এই পরীক্ষাটি ব্যর্থ হতে পারে। সেই অস্তিত্বের বিরুদ্ধে রক্ষা করতে, আপনাকে একাধিক সিপিইউ জুড়ে ধারাবাহিকতা পরীক্ষা করতে হবে।
কেভিন ক্লাইন 21

63

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

void doSomething(Widget widget) {
  if (widget != null) {
    widget.someMethod(); // ...
    ... // do more stuff with this widget
  }
}

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

/**
 * @param Widget widget Should never be null
 */
void doSomething(Widget widget) {
  assert widget != null;
  widget.someMethod(); // ...
    ... // do more stuff with this widget
}

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

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

void doSomething(Widget widget) {
  assert widget != null;
  if (widget != null) {
    widget.someMethod(); // ...
    ... // do more stuff with this widget
  }
}

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

এখানে একটি বাস্তব-বিশ্বের উদাহরণ: আমি একবার এমন একটি পদ্ধতি লিখেছিলাম যা সমতার জন্য দুটি স্বেচ্ছাচারিত মানের সাথে তুলনা করে, যেখানে উভয়ই মান বাতিল হতে পারে:

/**
 * Compare two values using equals(), after checking for null.
 * @param thisValue (may be null)
 * @param otherValue (may be null)
 * @return True if they are both null or if equals() returns true
 */
public static boolean compare(final Object thisValue, final Object otherValue) {
  boolean result;
  if (thisValue == null) {
    result = otherValue == null;
  } else {
    result = thisValue.equals(otherValue);
  }
  return result;
}

এই কোডটি equals()সেই ক্ষেত্রে পদ্ধতিটির কাজ প্রতিনিধিত্ব করে যেখানে এই মানটি নাল নয়। তবে এটি ধরে নিয়েছে যে equals()পদ্ধতিটি equals()নাল প্যারামিটারটি সঠিকভাবে পরিচালনা করে চুক্তিটি সঠিকভাবে পূরণ করে ।

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

public static boolean compare(final Object thisValue, final Object otherValue) {
  boolean result;
  if (thisValue == null) {
    result = otherValue == null;
  } else {
    result = otherValue != null && thisValue.equals(otherValue); // questionable null check
  }
  return result;
}

এখানে অতিরিক্ত চেক other != nullকেবলমাত্র প্রয়োজনীয়, যদি equals()পদ্ধতিটি তার চুক্তি অনুসারে প্রয়োজনীয় নাল পরীক্ষা করতে ব্যর্থ হয়।

বগি কোডটি আমাদের কোড বেসে রাখার প্রজ্ঞা সম্পর্কে আমার সহকর্মীর সাথে অকার্যকর বিতর্কে জড়ানোর পরিবর্তে আমি কোডটিতে কেবল দুটি দৃ as়তা রেখেছি। এই উক্তিগুলি আমাকে জানাতে দেবে, উন্নয়নের পর্যায়ে, যদি আমাদের ক্লাসগুলির কোনও একটি equals()সঠিকভাবে প্রয়োগ করতে ব্যর্থ হয় , তাই আমি এটিকে ঠিক করতে পারি:

public static boolean compare(final Object thisValue, final Object otherValue) {
  boolean result;
  if (thisValue == null) {
    result = otherValue == null;
    assert otherValue == null || otherValue.equals(null) == false;
  } else {
    result = otherValue != null && thisValue.equals(otherValue);
    assert thisValue.equals(null) == false;
  }
  return result;
}

মনে রাখা গুরুত্বপূর্ণ বিষয়গুলি হ'ল:

  1. জোর দেওয়া কেবলমাত্র উন্নয়ন-পর্বের সরঞ্জাম।

  2. একটি দৃser়তার বিষয়টি হ'ল আপনাকে জানাতে হবে যে কোনও বাগ আছে কিনা তা কেবল আপনার কোডেই নয়, আপনার কোড বেসে । (এখানে প্রাপ্ত প্রতিবেদনগুলি অন্যান্য শ্রেণিতে আসলে বাগগুলি পতাকাঙ্কিত করবে))

  3. এমনকি আমার সহকর্মী যদি নিশ্চিত হন যে আমাদের ক্লাসগুলি যথাযথভাবে লিখিত হয়েছিল, তবে এখানে দৃ the় পদক্ষেপগুলি কার্যকর হবে। নতুন ক্লাস যুক্ত করা হবে যা নাল পরীক্ষা করতে ব্যর্থ হতে পারে এবং এই পদ্ধতিটি আমাদের জন্য এই বাগগুলি পতাকাঙ্কিত করতে পারে।

  4. বিকাশের ক্ষেত্রে, আপনার লিখিত কোডটি দৃser় ব্যবহার না করা সত্ত্বেও, আপনার সর্বদা জোর চালু করা উচিত। আমার আইডিই কোনও নতুন এক্সিকিউটেবলের জন্য সর্বদা ডিফল্টরূপে এটি করতে সেট করে।

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

এছাড়াও, আপনার অস্থায়ী প্রতিস্থাপনের ব্যর্থতা যা আপনার ব্যর্থতার নীতিটি পরীক্ষা করা উচিত, যাতে লগ ফাইল বা আউটপুট স্ট্রিমের স্ট্যাক ট্রেসের মাধ্যমে আপনাকে নিশ্চিত করা যেতে পারে।


"একটি বাগ লুকিয়ে রাখা" এবং উন্নয়নের সময় কীভাবে বাগগুলি প্রকাশ করে তা সম্পর্কে ভাল পয়েন্টগুলি!
নোবার

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

20

assertকীওয়ার্ডটি কী করে তা ব্যাখ্যা করে অনেক ভাল উত্তর , তবে আসল প্রশ্নের উত্তর দেওয়া খুব কমই, " assertকীওয়ার্ডটি বাস্তব জীবনে কখন ব্যবহার করা উচিত ?"

উত্তর: প্রায় কখনও না

ধারণা হিসাবে দৃ .়ভাবে দুর্দান্ত। ভাল কোডের প্রচুর if (...) throw ...বিবৃতি রয়েছে (এবং তাদের আত্মীয়স্বজন পছন্দ করে Objects.requireNonNullএবং Math.addExact)। যাইহোক, নির্দিষ্ট নকশার সিদ্ধান্তগুলি assert কীওয়ার্ডের নিজস্বতা ব্যাপকভাবে সীমাবদ্ধ করেছে ।

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

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

সুতরাং, if (...) throw ...পাবলিক পদ্ধতির পরামিতি মানগুলি পরীক্ষা করার জন্য এবং নিক্ষেপ করার জন্য যেমন প্রয়োজন তেমনি ব্যবহারকেও অগ্রাধিকার দেওয়া উচিত IllegalArgumentException

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

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

(ভাড়া: জেভিএম ডেভসগুলি অবিস্মরণীয়, অকালপূর্বক অনুকূল কোডারদের একগুচ্ছ ছিল That এজন্য আপনি জাভা প্লাগইন এবং জেভিএম-তে সুরক্ষা সংক্রান্ত অনেকগুলি সমস্যা সম্পর্কে শুনেছেন They তারা উত্পাদনের কোডে বেসিক চেক এবং দৃ as়তাগুলি অন্তর্ভুক্ত করতে অস্বীকার করেছিল এবং আমরা অবিরত অবিরত আছি are মূল্য পরিশোধ করুন।)


2
@ অ্যাবারগ্লাস একটি ক্যাচ-সমস্ত ধারা catch (Throwable t)। আউট-মেমরিরির, অ্যাসারেশনআরার ইত্যাদি থেকে ফাঁদে ফেলা, লগ করা বা পুনরায় চেষ্টা / পুনরুদ্ধার করার চেষ্টা করার কোনও কারণ নেই
আলেকসান্দ্র ডাবিনস্কি

1
আমি আউটঅফমিউরিওর থেকে ধরেছি এবং পুনরুদ্ধার করেছি।
মিগুয়েলমুনোজ

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

2
@ মিগুয়েলমুনোজ আমার উত্তরে আমি বলেছি যে জোর দেওয়ার ধারণাটি খুব ভাল। এটি মূলশব্দটির বাস্তবায়ন assertখারাপ। আমি আমার উত্তরটি এটিকে আরও স্পষ্ট করতে সম্পাদনা করব যে আমি কীওয়ার্ডটি উল্লেখ করছি, ধারণাটি নয়।
আলেকসান্দ্র ডাবিনস্কি

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

14

এখানে সর্বাধিক সাধারণ ব্যবহারের কেস। মনে করুন আপনি একটি এনাম মান স্যুইচ করছেন:

switch (fruit) {
  case apple:
    // do something
    break;
  case pear:
    // do something
    break;
  case banana:
    // do something
    break;
}

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

switch (fruit) {
  case apple:
    // do something
    break;
  case pear:
    // do something
    break;
  case banana:
    // do something
    break;
  default:
    assert false : "Missing enum value: " + fruit;
}

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

9
কোনও ধরণের ব্যতিক্রমের চেয়ে উদাহরণস্বরূপ এখানে একটি দৃ as়তা কেন ব্যবহার করুন, উদাহরণস্বরূপ, একটি অবৈধ গেরুগের ধারণা?
liltitus27

4
AssertionErrorযদি দাবিগুলি সক্ষম করা থাকে তবে এটি একটি ছোঁড়াবে ( -ea)। উত্পাদনে কাঙ্ক্ষিত আচরণ কী? মৃত্যুদন্ড কার্যকর করার পরে একটি নীরব কোনও সম্ভাবনা এবং সম্ভাব্য বিপর্যয়? সম্ভবত না. আমি একটি স্পষ্ট পরামর্শ দিতে হবে throw new AssertionError("Missing enum value: " + fruit);
আইয়ুব

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

এটি ভুল বলে মনে হচ্ছে। আইএমএইচও আপনার ব্যবহার করা উচিত নয় defaultযাতে সংকলক আপনাকে হারিয়ে যাওয়া মামলায় সতর্ক করতে পারে। আপনি এর returnপরিবর্তে break(এটি পদ্ধতিটি উত্তোলনের প্রয়োজন হতে পারে) পরিবর্তে এবং তারপরে স্যুইচের পরে অনুপস্থিত কেসটি পরিচালনা করতে পারেন। এইভাবে আপনি সতর্কতা এবং একটি সুযোগ উভয়ই পাবেন assert
maarartinus

12

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

দৃ an়তার একটি উদাহরণ হতে পারে যে কোনও নির্দিষ্ট গ্রুপের পদ্ধতিটিকে সঠিক ক্রমে ডাকা হয়েছে কিনা তা পরীক্ষা করা (উদাহরণস্বরূপ, এটি hasNext()আগে next()একটি বলা হয় Iterator)।


1
পরের () এর আগে আপনাকে হ্যাশেক্সট () কল করতে হবে না।
ডিজেক্লেওয়ার্থ

6
@ ডিজেক্লেওয়ার্থ: আপনার পক্ষে আরম্ভের বক্তব্য এড়াতে হবে না। :-)
ডোনাল ফেলো

8

জাভাতে আসক্তি কীওয়ার্ডটি কী করে?

সংকলিত বাইকোডটি দেখি।

আমরা এই সিদ্ধান্তে পৌঁছে যাব:

public class Assert {
    public static void main(String[] args) {
        assert System.currentTimeMillis() == 0L;
    }
}

প্রায় ঠিক একই বাইকোড হিসাবে উত্পন্ন করে:

public class Assert {
    static final boolean $assertionsDisabled =
        !Assert.class.desiredAssertionStatus();
    public static void main(String[] args) {
        if (!$assertionsDisabled) {
            if (System.currentTimeMillis() != 0L) {
                throw new AssertionError();
            }
        }
    }
}

যেখানে Assert.class.desiredAssertionStatus()হয় trueযখন -eaঅন্যথায় কমান্ড লাইন পাস করা হয়েছে, এবং মিথ্যা।

আমরা System.currentTimeMillis()এটি নিশ্চিত করতে ব্যবহার করি যে এটি অপ্টিমাইজ হবে না ( assert true;শেষ হয়েছে)।

সিন্থেটিক ক্ষেত্রটি তৈরি করা হয়েছে যাতে জাভা কেবলমাত্র Assert.class.desiredAssertionStatus()লোড সময়ে একবার কল করতে পারে এবং এটি সেখানে ফলাফলটিকে ক্যাশে করে। আরও দেখুন: "স্ট্যাটিক সিনথেটিক" এর অর্থ কী?

আমরা এটি দিয়ে যাচাই করতে পারি:

javac Assert.java
javap -c -constants -private -verbose Assert.class

ওরাকল জেডিকে 1.8.0_45 এর সাহায্যে একটি সিন্থেটিক স্ট্যাটিক ফিল্ড তৈরি হয়েছিল (এটি দেখুন: "স্ট্যাটিক সিন্থেটিক" এর অর্থ কী? ):

static final boolean $assertionsDisabled;
  descriptor: Z
  flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC

স্ট্যাটিক ইনিশিয়ালাইজারের সাথে একসাথে:

 0: ldc           #6                  // class Assert
 2: invokevirtual #7                  // Method java/lang Class.desiredAssertionStatus:()Z
 5: ifne          12
 8: iconst_1
 9: goto          13
12: iconst_0
13: putstatic     #2                  // Field $assertionsDisabled:Z
16: return

এবং প্রধান পদ্ধতিটি হ'ল:

 0: getstatic     #2                  // Field $assertionsDisabled:Z
 3: ifne          22
 6: invokestatic  #3                  // Method java/lang/System.currentTimeMillis:()J
 9: lconst_0
10: lcmp
11: ifeq          22
14: new           #4                  // class java/lang/AssertionError
17: dup
18: invokespecial #5                  // Method java/lang/AssertionError."<init>":()V
21: athrow
22: return

আমরা এই সিদ্ধান্তে পৌঁছেছি:

  • এর জন্য কোনও বাইটকোড স্তর সমর্থন নেই assert: এটি একটি জাভা ভাষার ধারণা
  • assertকমান্ড লাইনে -Pcom.me.assert=trueপ্রতিস্থাপনের জন্য সিস্টেম বৈশিষ্ট্যগুলির সাথে বেশ ভালভাবে অনুকরণ করা যেতে পারে -eaএবং এ throw new AssertionError()

2
সুতরাং catch (Throwable t)ধারাটিও দৃser়তা লঙ্ঘন ধরতে সক্ষম? আমার জন্য যা তাদের ইউটিলিটি কেবলমাত্র সেই ক্ষেত্রে সীমাবদ্ধ করে যেখানে দৃ of়তার দাবিতে শরীর সময় সাপেক্ষ, যা বিরল।
এভেজেনি সার্জিভ

1
আমি নিশ্চিত নই কেন এটি দাবির কার্যকারিতা সীমাবদ্ধ করে। খুব বিরল ক্ষেত্রে বাদ দিয়ে আপনার কখনও থ্রোয়েবল ধরা উচিত নয়। আপনার যদি থ্রোয়েবল ধরার দরকার পড়ে তবে এটি দৃ as়ভাবে ধরা না পড়তে চান তবে আপনি কেবল AssertionErrorপ্রথমটি ধরতে পারেন এবং এটি আবার নতুন করে দেখতে পারেন।
মিগুয়েলমুনোজ

7

একটি বাস্তব বিশ্বের উদাহরণ, স্ট্যাক-ক্লাস থেকে ( জাভা নিবন্ধগুলিতে জোর দেওয়া থেকে )

public int pop() {
   // precondition
   assert !isEmpty() : "Stack is empty";
   return stack[--num];
}

80
এটি সি তে বোঝা যাবে: একটি দৃ as়তা এমন কিছু যা সত্যই কখনও ঘটতে হবে না - খালি স্ট্যাকের পপিংয়ের ফলে লাইন বরাবর একটি NoElementsException বা কিছু নিক্ষেপ করা উচিত। ডোনালের উত্তর দেখুন।
কোনারাক

4
আমি রাজী. যদিও এটি একটি সরকারী টিউটোরিয়াল থেকে নেওয়া হয়েছে, এটি একটি খারাপ উদাহরণ।
ডিজেক্লেওয়ার্থ


7
সেখানে সম্ভবত একটি স্মৃতি ফুটো আছে। আপনার স্ট্যাক সেট করা উচিত [num] = নাল; জিসি সঠিকভাবে তার কাজ করার জন্য।
এইচ.রাবি

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

7

একটি দৃser়তা কোডের ত্রুটিগুলি সনাক্ত করার অনুমতি দেয়। আপনার প্রোগ্রামটি উত্পাদন চলাকালীন আপনি পরীক্ষার জন্য এবং ডিবাগিংয়ের জন্য দৃ as়তাগুলি চালু করতে পারেন।

আপনি যখন সত্য তা জানেন তখন কেন কিছু দৃ as়তার সাথে বলবেন? এটি তখনই সত্য যখন সমস্ত কিছু সঠিকভাবে কাজ করে। প্রোগ্রামটির যদি কোনও ত্রুটি থাকে তবে এটি সম্ভবত সত্য না। প্রক্রিয়াটির আগে এটি সনাক্তকরণ আপনাকে কিছু ভুল বলে দেয়।

একটি assertবিবৃতিতে statementচ্ছিক Stringবার্তার পাশাপাশি এই বিবৃতি রয়েছে ।

দৃsert় বিবৃতিটির বাক্য গঠনের দুটি রূপ রয়েছে:

assert boolean_expression;
assert boolean_expression: error_message;

এখানে কয়েকটি মৌলিক নিয়ম রয়েছে যা পরিচালনা করে যেখানে দাবিগুলি ব্যবহার করা উচিত এবং কোথায় সেগুলি ব্যবহার করা উচিত নয়। দৃser়তার জন্য ব্যবহার করা উচিত :

  1. একটি ব্যক্তিগত পদ্ধতির ইনপুট প্যারামিটার বৈধকরণ। পাবলিক পদ্ধতির জন্য নয়publicখারাপ পরামিতিগুলি পাস করার সময় পদ্ধতিগুলি নিয়মিত ব্যতিক্রম ছুঁড়ে ফেলা উচিত।

  2. প্রোগ্রামের যে কোনও জায়গায় কোনও সত্যের সত্যতা যা নিশ্চিতভাবেই সত্য ensure

উদাহরণস্বরূপ, আপনি যদি নিশ্চিত হন যে এটি কেবলমাত্র 1 বা 2 হয়, আপনি এই জাতীয় অবস্থান ব্যবহার করতে পারেন:

...
if (i == 1)    {
    ...
}
else if (i == 2)    {
    ...
} else {
    assert false : "cannot happen. i is " + i;
}
...
  1. কোনও পদ্ধতি শেষে পোস্ট শর্তাদি বৈধকরণ। এর অর্থ, ব্যবসায়িক যুক্তি সম্পাদন করার পরে, আপনি আপনার পরিবর্তনগুলি বা ফলাফলের অভ্যন্তরীণ অবস্থাটি আপনার প্রত্যাশার সাথে সামঞ্জস্যপূর্ণ তা নিশ্চিত করতে আপনি দৃser়তাগুলি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, সকেট বা ফাইলটি সত্যই খোলা আছে তা নিশ্চিত করার জন্য কোনও পদ্ধতি যা সকেট বা একটি ফাইল খোলায় শেষে শেষে একটি দৃ use়তা ব্যবহার করতে পারে।

দৃser়তাগুলি এর জন্য ব্যবহার করা উচিত নয় :

  1. সর্বজনীন পদ্ধতির ইনপুট প্যারামিটার বৈধকরণ। যেহেতু দাবিগুলি সর্বদা কার্যকর করা যায় না, তাই নিয়মিত ব্যতিক্রম প্রক্রিয়াটি ব্যবহার করা উচিত।

  2. ব্যবহারকারীর দ্বারা ইনপুট এমন কোনও কিছুর প্রতিবন্ধকতা বৈধকরণ। উপরের মতই.

  3. পার্শ্ব প্রতিক্রিয়া জন্য ব্যবহার করা উচিত নয়।

উদাহরণস্বরূপ এটি যথাযথ ব্যবহার নয় কারণ এখানে দৃ as়তাটি doSomething()পদ্ধতিটির কলিংয়ের পার্শ্ব প্রতিক্রিয়ার জন্য ব্যবহৃত হয় ।

public boolean doSomething() {
...    
}
public void someMethod() {       
assert doSomething(); 
}

আপনি যখন আপনার কোডটিতে দৃser়তা জোর করে কিনা তা সন্ধান করার চেষ্টা করছেন তখন কেবল এটিই ন্যায়সঙ্গত হতে পারে could   

boolean enabled = false;    
assert enabled = true;    
if (enabled) {
    System.out.println("Assertions are enabled");
} else {
    System.out.println("Assertions are disabled");
}

5

এখানে সরবরাহিত সমস্ত দুর্দান্ত উত্তর ছাড়াও, অফিসিয়াল জাভা এসই 7 প্রোগ্রামিং গাইডটিতে ব্যবহারের জন্য একটি সুন্দর সংক্ষিপ্ত ম্যানুয়াল রয়েছে assert; দৃ as়পদগুলি ব্যবহার করার জন্য এটি কখন ভাল (এবং, গুরুত্বপূর্ণভাবে খারাপ) ধারণা এবং এটি কীভাবে ব্যতিক্রম ছোঁড়া থেকে পৃথক several

লিংক


1
আমি রাজী. নিবন্ধটিতে অনেক দুর্দান্ত উদাহরণ রয়েছে। যখন অবজেক্টটি কোনও লক ধরে তখনই কোনও পদ্ধতিটি ডাকা হয় তা নিশ্চিত করার জন্য আমি বিশেষত এটি পছন্দ করেছি।
মিগুয়েলমুনোজ

4

বিকাশকালে দৃsert়তা খুব কার্যকর। যখন আপনি কিছু ব্যবহার করতে পারবেন না তখন আপনি এটি ব্যবহার করুনআপনার কোডটি সঠিকভাবে কাজ করছে ঘটতে পারলে । এটি ব্যবহার করা সহজ, এবং কোডে চিরকালের জন্য থাকতে পারে, কারণ এটি বাস্তব জীবনে বন্ধ হয়ে যাবে।

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

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


1

আমি মনে করি না অ্যান্ড্রয়েডে সম্পদগুলি চালু করার কোনও উপায় আছে। এটি খুব হতাশাব্যঞ্জক।
মিগুয়েলমুনোজ

3

একটি হাইবারনেট / এসকিউএল প্রকল্পের জন্য আমি একটি সার্ভারে লিখেছিলাম এমন একটি দাবি। একটি সত্তা শিমের দুটি কার্যকরভাবে-বুলিয়ান বৈশিষ্ট্য ছিল, যাকে বলা হয় আইস্যাকটিভ এবং ইজ ডিফল্ট। প্রত্যেকের "Y" বা "N" বা নাল মান হতে পারে, যা "N" হিসাবে বিবেচিত হয়েছিল। আমরা নিশ্চিত করতে চাই যে ব্রাউজার ক্লায়েন্টটি এই তিনটি মানের মধ্যে সীমাবদ্ধ। সুতরাং, এই দুটি বৈশিষ্ট্যের জন্য আমার সেটারগুলিতে, আমি এই দাবিটি যুক্ত করেছি:

assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;

নিম্নলিখিত নোট করুন।

  1. এই দাবী কেবলমাত্র উন্নয়নের পর্যায়ে। যদি ক্লায়েন্ট কোনও খারাপ মান প্রেরণ করে তবে আমরা তাড়াতাড়ি ধরব এবং আমাদের উত্পাদনে পৌঁছানোর অনেক আগেই এটি ঠিক করব। জোর দেওয়া ত্রুটিগুলির জন্য যা আপনি তাড়াতাড়ি ধরতে পারেন।

  2. এই দাবিটি ধীর এবং অদক্ষ। ঠিক আছে. দৃ slow়তা ধীর হতে মুক্ত। তারা যত্নশীল না কারণ তারা কেবলমাত্র উন্নয়ন সরঞ্জাম development এটি উত্পাদন কোডটি ধীর করবে না কারণ দাবিগুলি অক্ষম করা হবে। (এই বিষয়ে কিছু মতভেদ আছে, যা আমি পরে যাব।) এটি আমার পরবর্তী বিষয়টিকে নিয়ে যায়।

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

  4. এই দাবিটি ক্লায়েন্টের সঠিক ক্রিয়াকলাপ যাচাই করার জন্য বিদ্যমান। সুতরাং আমরা যখন প্রযোজনায় পৌঁছাচ্ছি ততক্ষণে আমরা নিশ্চিত হয়েছি যে ক্লায়েন্টটি সঠিকভাবে কাজ করছে, তাই আমরা নিরাপদে দৃ the়তা বন্ধ করতে পারি।

  5. কিছু লোক এটি জিজ্ঞাসা করে: যদি উত্পাদনে দৃser়তার প্রয়োজন হয় না, আপনি যখন কাজ শেষ করেন তখন কেন তাদের বাইরে নিয়ে যান না? কারণ আপনি পরবর্তী সংস্করণে কাজ শুরু করার সময় আপনার এখনও তাদের প্রয়োজন।

কিছু লোক যুক্তি দেখিয়েছেন যে আপনার কখনই দাবিগুলি ব্যবহার করা উচিত নয়, কারণ আপনি কখনই নিশ্চিত হতে পারবেন না যে সমস্ত বাগগুলি চলে গেছে, সুতরাং আপনার এগুলি এমনকি উত্পাদন পর্যন্ত রাখা উচিত to এবং সুতরাং দৃsert় বক্তব্যটি ব্যবহার করার কোনও অর্থ নেই, যেহেতু দাবি করার একমাত্র সুবিধা হ'ল আপনি সেগুলি বন্ধ করতে পারেন। অতএব, এই চিন্তাভাবনা অনুসারে, আপনার (প্রায়) কখনই আসক্তি ব্যবহার করা উচিত নয়। আমি একমত নই এটি অবশ্যই সত্য যে কোনও পরীক্ষা যদি উত্পাদনের সাথে সম্পর্কিত হয় তবে আপনার দৃ an়তা ব্যবহার করা উচিত নয়। কিন্তু এই পরীক্ষাটি করে না উৎপাদনে অন্তর্গত। এটি একটি এমন বাগটি ধরার জন্য যা সম্ভবত কখনও উত্পাদনে পৌঁছায় না, সুতরাং আপনার কাজ শেষ হয়ে গেলে এটি নিরাপদে বন্ধ হয়ে যেতে পারে।

বিটিডাব্লু, আমি এটি এইভাবে লিখতে পারতাম:

assert value == null || value.equals("Y") || value.equals("N") : value;

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


আমি দৃঢ়ভাবে সন্দেহ যেমন একটি ব্যবহার করে অতি ক্ষুদ্র একটি HashSetযদি কোনো ওভার কোনো গতি সুবিধা এনেছে ArrayList। তদ্ব্যতীত, সেট এবং তালিকার ক্রিয়েশনগুলি লুকের সময়কে প্রাধান্য দেয়। ধ্রুবক ব্যবহার করার সময় তারা ভাল হয়ে যাবে। সব বলেছে, +1।
মার্টিনাস

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

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

2

মূলত অ্যাপ্লিকেশনটি ডিবাগ করার জন্য দৃser়তা ব্যবহৃত হয় বা কোনও অ্যাপ্লিকেশনটির বৈধতা পরীক্ষা করতে কিছু অ্যাপ্লিকেশন ব্যতিক্রম হ্যান্ডলিংয়ের পরিবর্তে ব্যবহৃত হয়।

দৃser়তা রান সময় কাজ করে। একটি সাধারণ উদাহরণ, যা পুরো ধারণাটি খুব সহজভাবে ব্যাখ্যা করতে পারে, এখানে রয়েছে - জোড় শব্দক শব্দটি কী করে? (WikiAnswers)।


2

দাবিগুলি ডিফল্টরূপে অক্ষম থাকে। তাদের সক্ষম করতে আমাদের অবশ্যই -eaবিকল্পগুলি সহ প্রোগ্রামটি চালাতে হবে (গ্রানুলারিটি বিভিন্ন রকম হতে পারে)। উদাহরণস্বরূপ java -ea AssertionsDemo,।

আসক্তিগুলি ব্যবহারের জন্য দুটি ফর্ম্যাট রয়েছে:

  1. সরল: যেমন। assert 1==2; // This will raise an AssertionError
  2. আরও ভাল: assert 1==2: "no way.. 1 is not equal to 2"; এটি প্রদর্শিত বার্তাটি দিয়ে খুব বেশি উত্সাহ দেয় এবং এটি আরও ভাল। যদিও প্রকৃত সিনট্যাক্সটি assert expr1:expr2সেখানে যেখানে expr2 কোনও মান ফেরত দেওয়া কোনও অভিব্যক্তি হতে পারে, আমি বার্তাটি মুদ্রণের জন্য এটি প্রায়শই ব্যবহার করেছি।

1

পুনরুদ্ধার করতে (এবং এটি শুধুমাত্র জাভা নয় অনেক ভাষার ক্ষেত্রেই সত্য):

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

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

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

ব্যতিক্রমগুলি মারাত্মক-ত্রুটির শর্তগুলি সুবিধামত মঞ্জুরি দেয় যা তারা হ'ল: "নিয়মের ব্যতিক্রম" " এবং, তাদের জন্য কোনও কোড-পাথ পরিচালনা করা হবে যা "নিয়মের ব্যতিক্রম ... " বলের উড়ে! "


1

জোর দেওয়া চেক যা বন্ধ হতে পারে। এগুলি খুব কমই ব্যবহৃত হয়। কেন?

  • এগুলি অবশ্যই সর্বজনীন পদ্ধতির আর্গুমেন্টগুলি পরীক্ষা করার জন্য ব্যবহার করা উচিত নয় কারণ তাদের উপর আপনার কোনও নিয়ন্ত্রণ নেই।
  • এগুলিকে সাধারণ চেকগুলির জন্য ব্যবহার করা উচিত নয় result != nullকারণ এ জাতীয় চেকগুলি খুব দ্রুত এবং সংরক্ষণ করার মতো খুব কমই কিছু আছে।

তো, কী বাকি? অবস্থার জন্য ব্যয়বহুল চেকগুলি সত্য বলে আশা করা হচ্ছে । একটি ভাল উদাহরণ হ'ল আরবি-ট্রি এর মতো ডেটা স্ট্রাকচারের আক্রমণকারী। প্রকৃতপক্ষে, ConcurrentHashMapজেডিকে 8-তে, এরকম কয়েকটি অর্থবহ আসক্তি রয়েছে TreeNodes

  • আপনি সত্যিই তাদের উত্পাদনে স্যুইচ করতে চান না কারণ তারা সহজে রান রানকে আধিপত্য করতে পারে।
  • পরীক্ষার সময় আপনি সেগুলি চালু বা বন্ধ করতে চাইতে পারেন।
  • কোডটিতে কাজ করার সময় আপনি অবশ্যই সেগুলিকে স্যুইচ করতে চান।

কখনও কখনও, চেকটি সত্যই ব্যয়বহুল নয় তবে একই সাথে আপনিও নিশ্চিত যে এটি পাস হয়ে যাবে। আমার কোডে, যেমন,

assert Sets.newHashSet(userIds).size() == userIds.size();

যেখানে আমি নিশ্চিত যে আমি সবে তৈরি করা তালিকার অনন্য উপাদান রয়েছে তবে আমি এটি নথিভুক্ত করে ডাবল চেক করতে চেয়েছিলাম।


0

মূলত, "assert true" পাস হবে এবং "assert false" ব্যর্থ হবে। আসুন দেখে নেওয়া যাক এটি কীভাবে কাজ করবে:

public static void main(String[] args)
{
    String s1 = "Hello";
    assert checkInteger(s1);
}

private static boolean checkInteger(String s)
{
    try {
        Integer.parseInt(s);
        return true;
    }
    catch(Exception e)
    {
        return false;
    }
}

-8

assertএকটি কীওয়ার্ড। এটি জেডিকে ২.৪ এ প্রবর্তিত হয়েছিল। দুটি ধরণের assertএস

  1. খুব সাধারণ assertবক্তব্য
  2. সহজ assertবক্তব্য।

ডিফল্টরূপে সমস্ত assertবিবৃতি কার্যকর করা হবে না। যদি কোনও assertবিবৃতি মিথ্যা পায় তবে তা স্বয়ংক্রিয়ভাবে একটি ত্রুটি উত্থাপন করবে।


1
এটি কোনও বাস্তব জীবনের উদাহরণ সরবরাহ করে না, যা প্রশ্নের লক্ষ্য
রুবেনাফো

1
আপনি কি কেবল পেস্টটি অনুলিপি করেছেন: amazon.com/Programmer- স্টুডি-1Z0-803-1Z0-804- সার্টিফিকেশন / ডিপি / ??
Koray Tugay
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.