দৃser়তার মূল ভূমিকা বোঝার জন্য কিছু বাস্তব জীবনের উদাহরণ কী কী?
দৃser়তার মূল ভূমিকা বোঝার জন্য কিছু বাস্তব জীবনের উদাহরণ কী কী?
উত্তর:
গবেষকেরা (প্রণালী দ্বারা জাহির শব্দ) জাভা 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;
}
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/…
আসুন ধরে নেওয়া যাক যে আপনি একটি পারমাণবিক বিদ্যুৎকেন্দ্র নিয়ন্ত্রণ করতে একটি প্রোগ্রাম লেখার কথা। এটি বেশ সুস্পষ্ট এমনকি সবচেয়ে ছোটখাট ভুল সর্বনাশা ফলাফল হতে পারে যে, তাই আপনার কোড করা হয়েছে বাগ বিনামূল্যে (বলা যাচ্ছে যে জেভিএম বাগ বিনামূল্যে তর্কের খাতিরে যায়)।
জাভা কোনও যাচাইযোগ্য ভাষা নয়, যার অর্থ: আপনি গণনা করতে পারবেন না যে আপনার অপারেশনের ফলাফলটি নিখুঁত হবে। এর প্রধান কারণ পয়েন্টার: তারা কোথাও বা কোথাও নির্দেশ করতে পারে, সুতরাং এগুলি এই সঠিক মূল্যের হিসাবে গণনা করা যায় না, কমপক্ষে কোডের যুক্তিসঙ্গত ব্যাখ্যার মধ্যে নয়। এই সমস্যাটি দেওয়া, প্রমাণ করার কোনও উপায় নেই যে আপনার কোডটি পুরোপুরি সঠিক। তবে আপনি যা করতে পারেন তা হ'ল এটি প্রমাণ করা যে এটি ঘটলে আপনি কমপক্ষে প্রতিটি বাগ খুঁজে পান।
এই ধারণাটি ডিজাইন-বাই-কন্ট্রাক্ট (ডিবিসি) দৃষ্টান্তের উপর ভিত্তি করে : আপনি প্রথমে আপনার পদ্ধতিটি কী করণীয় তা নির্ধারণ করেন (গাণিতিক নির্ভুলতার সাথে) এবং তারপরে প্রকৃত বাস্তবায়নের সময় এটি পরীক্ষা করে এটি যাচাই করুন। উদাহরণ:
// 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়তাগুলি ব্যবহার করতে হবে। এটি করার ফলে আপনার কোডটি ফুলে উঠবে, তবে শেষ পর্যন্ত আপনি আশ্চর্যজনকভাবে স্বল্প বিকাশের সময় কোনও পণ্য সরবরাহ করতে পারেন (এর আগে আপনি কোনও বাগ ঠিক করেন, ব্যয়টি কম হবে)। এবং অতিরিক্ত: আপনার কোডের মধ্যে যদি কোনও বাগ থাকে তবে আপনি এটি সনাক্ত করতে পারবেন। কোনও ত্রুটির পিছলে পিছলে যাওয়ার এবং পরে সমস্যার কারণ হওয়ার কোনও উপায় নেই।
এটি তবুও বাগ-মুক্ত কোডের কোনও গ্যারান্টি নয়, তবে এটি সাধারণ প্রোগ্রামের চেয়ে অনেক বেশি কাছে।
new IllegalArgumentException
বার্তাটি দিয়ে কেবল একটি নিক্ষেপ করা দৃsert় ব্যবহারের পরিবর্তে কী পার্থক্য রয়েছে ? আমি বলতে চাইছি, অন্য throws
কোনও পদ্ধতিতে এই ব্যতিক্রমটি পরিচালনা করার জন্য পদ্ধতি ঘোষণা এবং কোডে ওপেন করা উচিত। কেন assert
নতুন ব্যতিক্রম নিক্ষেপ ইনসেটেড? বা কেন একটি if
পরিবর্তে না assert
? সত্যিই এটি পাওয়া যায় না :(
a
নেতিবাচক হতে পারে তবে ভুল । দ্বিতীয় দৃ়তা অকেজো; ইনট মানগুলির জন্য, এটি সর্বদা ক্ষেত্রে + বি - বি == এ ক্ষেত্রে হয়। কম্পিউটারটি মৌলিকভাবে ভেঙে গেলে এই পরীক্ষাটি ব্যর্থ হতে পারে। সেই অস্তিত্বের বিরুদ্ধে রক্ষা করতে, আপনাকে একাধিক সিপিইউ জুড়ে ধারাবাহিকতা পরীক্ষা করতে হবে।
আপনার কোডগুলিতে বাগগুলি ধরার জন্য উত্সগুলি একটি উন্নয়ন-পর্বের সরঞ্জাম। এগুলি সহজেই মুছে ফেলার জন্য নকশাকৃত করা হয়েছে, সুতরাং তারা উত্পাদন কোডে বিদ্যমান থাকবে না। সুতরাং জোর দেওয়া আপনার "গ্রাহকের কাছে বিতরণ করা" সমাধানের অংশ নয়। আপনি যে অনুমান করছেন তা সঠিক কিনা তা নিশ্চিত করার জন্য তারা অভ্যন্তরীণ চেক। নাল পরীক্ষা করা সবচেয়ে সাধারণ উদাহরণ। অনেক পদ্ধতি এইভাবে লেখা হয়:
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;
}
মনে রাখা গুরুত্বপূর্ণ বিষয়গুলি হ'ল:
জোর দেওয়া কেবলমাত্র উন্নয়ন-পর্বের সরঞ্জাম।
একটি দৃser়তার বিষয়টি হ'ল আপনাকে জানাতে হবে যে কোনও বাগ আছে কিনা তা কেবল আপনার কোডেই নয়, আপনার কোড বেসে । (এখানে প্রাপ্ত প্রতিবেদনগুলি অন্যান্য শ্রেণিতে আসলে বাগগুলি পতাকাঙ্কিত করবে))
এমনকি আমার সহকর্মী যদি নিশ্চিত হন যে আমাদের ক্লাসগুলি যথাযথভাবে লিখিত হয়েছিল, তবে এখানে দৃ the় পদক্ষেপগুলি কার্যকর হবে। নতুন ক্লাস যুক্ত করা হবে যা নাল পরীক্ষা করতে ব্যর্থ হতে পারে এবং এই পদ্ধতিটি আমাদের জন্য এই বাগগুলি পতাকাঙ্কিত করতে পারে।
বিকাশের ক্ষেত্রে, আপনার লিখিত কোডটি দৃser় ব্যবহার না করা সত্ত্বেও, আপনার সর্বদা জোর চালু করা উচিত। আমার আইডিই কোনও নতুন এক্সিকিউটেবলের জন্য সর্বদা ডিফল্টরূপে এটি করতে সেট করে।
জবাবগুলি উত্পাদনে কোডের আচরণের পরিবর্তন করে না, তাই আমার সহকর্মী খুশী যে নাল চেক রয়েছে, এবং equals()
পদ্ধতিটি বাগিচা থাকলেও এই পদ্ধতিটি সঠিকভাবে কার্যকর হবে will আমি খুশি কারণ আমি equals()
বিকাশের যে কোনও বগি পদ্ধতি ধরব ।
এছাড়াও, আপনার অস্থায়ী প্রতিস্থাপনের ব্যর্থতা যা আপনার ব্যর্থতার নীতিটি পরীক্ষা করা উচিত, যাতে লগ ফাইল বা আউটপুট স্ট্রিমের স্ট্যাক ট্রেসের মাধ্যমে আপনাকে নিশ্চিত করা যেতে পারে।
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 মূল্য পরিশোধ করুন।)
catch (Throwable t)
। আউট-মেমরিরির, অ্যাসারেশনআরার ইত্যাদি থেকে ফাঁদে ফেলা, লগ করা বা পুনরায় চেষ্টা / পুনরুদ্ধার করার চেষ্টা করার কোনও কারণ নেই
assert
খারাপ। আমি আমার উত্তরটি এটিকে আরও স্পষ্ট করতে সম্পাদনা করব যে আমি কীওয়ার্ডটি উল্লেখ করছি, ধারণাটি নয়।
এখানে সর্বাধিক সাধারণ ব্যবহারের কেস। মনে করুন আপনি একটি এনাম মান স্যুইচ করছেন:
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;
}
AssertionError
যদি দাবিগুলি সক্ষম করা থাকে তবে এটি একটি ছোঁড়াবে ( -ea
)। উত্পাদনে কাঙ্ক্ষিত আচরণ কী? মৃত্যুদন্ড কার্যকর করার পরে একটি নীরব কোনও সম্ভাবনা এবং সম্ভাব্য বিপর্যয়? সম্ভবত না. আমি একটি স্পষ্ট পরামর্শ দিতে হবে throw new AssertionError("Missing enum value: " + fruit);
।
default
যাতে সংকলক আপনাকে হারিয়ে যাওয়া মামলায় সতর্ক করতে পারে। আপনি এর return
পরিবর্তে break
(এটি পদ্ধতিটি উত্তোলনের প্রয়োজন হতে পারে) পরিবর্তে এবং তারপরে স্যুইচের পরে অনুপস্থিত কেসটি পরিচালনা করতে পারেন। এইভাবে আপনি সতর্কতা এবং একটি সুযোগ উভয়ই পাবেন assert
।
জরুরী পোস্ট-শর্তগুলি পরীক্ষা করতে ব্যবহৃত হয় এবং প্রাক-শর্তগুলি "কখনই ব্যর্থ হয় না"। সঠিক কোডটি কখনও দৃ fail়তার সাথে ব্যর্থ হওয়া উচিত নয়; যখন তারা ট্রিগার করে, তখন তাদের একটি বাগ নির্দেশ করা উচিত (আশাকরি এমন কোনও স্থানে যেখানে সমস্যার আসল লোকস রয়েছে তার নিকটে)।
দৃ an়তার একটি উদাহরণ হতে পারে যে কোনও নির্দিষ্ট গ্রুপের পদ্ধতিটিকে সঠিক ক্রমে ডাকা হয়েছে কিনা তা পরীক্ষা করা (উদাহরণস্বরূপ, এটি hasNext()
আগে next()
একটি বলা হয় Iterator
)।
জাভাতে আসক্তি কীওয়ার্ডটি কী করে?
সংকলিত বাইকোডটি দেখি।
আমরা এই সিদ্ধান্তে পৌঁছে যাব:
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()
।catch (Throwable t)
ধারাটিও দৃser়তা লঙ্ঘন ধরতে সক্ষম? আমার জন্য যা তাদের ইউটিলিটি কেবলমাত্র সেই ক্ষেত্রে সীমাবদ্ধ করে যেখানে দৃ of়তার দাবিতে শরীর সময় সাপেক্ষ, যা বিরল।
AssertionError
প্রথমটি ধরতে পারেন এবং এটি আবার নতুন করে দেখতে পারেন।
একটি বাস্তব বিশ্বের উদাহরণ, স্ট্যাক-ক্লাস থেকে ( জাভা নিবন্ধগুলিতে জোর দেওয়া থেকে )
public int pop() {
// precondition
assert !isEmpty() : "Stack is empty";
return stack[--num];
}
একটি দৃser়তা কোডের ত্রুটিগুলি সনাক্ত করার অনুমতি দেয়। আপনার প্রোগ্রামটি উত্পাদন চলাকালীন আপনি পরীক্ষার জন্য এবং ডিবাগিংয়ের জন্য দৃ as়তাগুলি চালু করতে পারেন।
আপনি যখন সত্য তা জানেন তখন কেন কিছু দৃ as়তার সাথে বলবেন? এটি তখনই সত্য যখন সমস্ত কিছু সঠিকভাবে কাজ করে। প্রোগ্রামটির যদি কোনও ত্রুটি থাকে তবে এটি সম্ভবত সত্য না। প্রক্রিয়াটির আগে এটি সনাক্তকরণ আপনাকে কিছু ভুল বলে দেয়।
একটি assert
বিবৃতিতে statementচ্ছিক String
বার্তার পাশাপাশি এই বিবৃতি রয়েছে ।
দৃsert় বিবৃতিটির বাক্য গঠনের দুটি রূপ রয়েছে:
assert boolean_expression;
assert boolean_expression: error_message;
এখানে কয়েকটি মৌলিক নিয়ম রয়েছে যা পরিচালনা করে যেখানে দাবিগুলি ব্যবহার করা উচিত এবং কোথায় সেগুলি ব্যবহার করা উচিত নয়। দৃser়তার জন্য ব্যবহার করা উচিত :
একটি ব্যক্তিগত পদ্ধতির ইনপুট প্যারামিটার বৈধকরণ। পাবলিক পদ্ধতির জন্য নয় । public
খারাপ পরামিতিগুলি পাস করার সময় পদ্ধতিগুলি নিয়মিত ব্যতিক্রম ছুঁড়ে ফেলা উচিত।
প্রোগ্রামের যে কোনও জায়গায় কোনও সত্যের সত্যতা যা নিশ্চিতভাবেই সত্য ensure
উদাহরণস্বরূপ, আপনি যদি নিশ্চিত হন যে এটি কেবলমাত্র 1 বা 2 হয়, আপনি এই জাতীয় অবস্থান ব্যবহার করতে পারেন:
...
if (i == 1) {
...
}
else if (i == 2) {
...
} else {
assert false : "cannot happen. i is " + i;
}
...
দৃser়তাগুলি এর জন্য ব্যবহার করা উচিত নয় :
সর্বজনীন পদ্ধতির ইনপুট প্যারামিটার বৈধকরণ। যেহেতু দাবিগুলি সর্বদা কার্যকর করা যায় না, তাই নিয়মিত ব্যতিক্রম প্রক্রিয়াটি ব্যবহার করা উচিত।
ব্যবহারকারীর দ্বারা ইনপুট এমন কোনও কিছুর প্রতিবন্ধকতা বৈধকরণ। উপরের মতই.
পার্শ্ব প্রতিক্রিয়া জন্য ব্যবহার করা উচিত নয়।
উদাহরণস্বরূপ এটি যথাযথ ব্যবহার নয় কারণ এখানে দৃ 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");
}
এখানে সরবরাহিত সমস্ত দুর্দান্ত উত্তর ছাড়াও, অফিসিয়াল জাভা এসই 7 প্রোগ্রামিং গাইডটিতে ব্যবহারের জন্য একটি সুন্দর সংক্ষিপ্ত ম্যানুয়াল রয়েছে assert
; দৃ as়পদগুলি ব্যবহার করার জন্য এটি কখন ভাল (এবং, গুরুত্বপূর্ণভাবে খারাপ) ধারণা এবং এটি কীভাবে ব্যতিক্রম ছোঁড়া থেকে পৃথক several
বিকাশকালে দৃsert়তা খুব কার্যকর। যখন আপনি কিছু ব্যবহার করতে পারবেন না তখন আপনি এটি ব্যবহার করুনআপনার কোডটি সঠিকভাবে কাজ করছে ঘটতে পারলে । এটি ব্যবহার করা সহজ, এবং কোডে চিরকালের জন্য থাকতে পারে, কারণ এটি বাস্তব জীবনে বন্ধ হয়ে যাবে।
যদি বাস্তব জীবনে পরিস্থিতি দেখা দেওয়ার কোনও সম্ভাবনা থাকে তবে আপনাকে অবশ্যই এটি পরিচালনা করতে হবে।
আমি এটি পছন্দ করি, তবে কীভাবে এটি গ্রহন / অ্যান্ড্রয়েড / এডিটিতে চালু করবেন তা জানেন না। এটি ডিবাগ করার সময়ও বন্ধ রয়েছে বলে মনে হচ্ছে। (এটিতে একটি থ্রেড রয়েছে তবে এটি 'জাভা ভিএম' বোঝায় যা এডিটি রান কনফিগারেশনে উপস্থিত হয় না)।
একটি হাইবারনেট / এসকিউএল প্রকল্পের জন্য আমি একটি সার্ভারে লিখেছিলাম এমন একটি দাবি। একটি সত্তা শিমের দুটি কার্যকরভাবে-বুলিয়ান বৈশিষ্ট্য ছিল, যাকে বলা হয় আইস্যাকটিভ এবং ইজ ডিফল্ট। প্রত্যেকের "Y" বা "N" বা নাল মান হতে পারে, যা "N" হিসাবে বিবেচিত হয়েছিল। আমরা নিশ্চিত করতে চাই যে ব্রাউজার ক্লায়েন্টটি এই তিনটি মানের মধ্যে সীমাবদ্ধ। সুতরাং, এই দুটি বৈশিষ্ট্যের জন্য আমার সেটারগুলিতে, আমি এই দাবিটি যুক্ত করেছি:
assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;
নিম্নলিখিত নোট করুন।
এই দাবী কেবলমাত্র উন্নয়নের পর্যায়ে। যদি ক্লায়েন্ট কোনও খারাপ মান প্রেরণ করে তবে আমরা তাড়াতাড়ি ধরব এবং আমাদের উত্পাদনে পৌঁছানোর অনেক আগেই এটি ঠিক করব। জোর দেওয়া ত্রুটিগুলির জন্য যা আপনি তাড়াতাড়ি ধরতে পারেন।
এই দাবিটি ধীর এবং অদক্ষ। ঠিক আছে. দৃ slow়তা ধীর হতে মুক্ত। তারা যত্নশীল না কারণ তারা কেবলমাত্র উন্নয়ন সরঞ্জাম development এটি উত্পাদন কোডটি ধীর করবে না কারণ দাবিগুলি অক্ষম করা হবে। (এই বিষয়ে কিছু মতভেদ আছে, যা আমি পরে যাব।) এটি আমার পরবর্তী বিষয়টিকে নিয়ে যায়।
এই দাবির কোনও পার্শ্ব প্রতিক্রিয়া নেই। আমি একটি অমার্জনীয়যোগ্য স্থিতিশীল চূড়ান্ত সেটটির বিপরীতে আমার মানটি পরীক্ষা করতে পারতাম, তবে সে সেটটি প্রায় উত্পাদনে থাকত, যেখানে এটি কখনও ব্যবহার না হত।
এই দাবিটি ক্লায়েন্টের সঠিক ক্রিয়াকলাপ যাচাই করার জন্য বিদ্যমান। সুতরাং আমরা যখন প্রযোজনায় পৌঁছাচ্ছি ততক্ষণে আমরা নিশ্চিত হয়েছি যে ক্লায়েন্টটি সঠিকভাবে কাজ করছে, তাই আমরা নিরাপদে দৃ the়তা বন্ধ করতে পারি।
কিছু লোক এটি জিজ্ঞাসা করে: যদি উত্পাদনে দৃser়তার প্রয়োজন হয় না, আপনি যখন কাজ শেষ করেন তখন কেন তাদের বাইরে নিয়ে যান না? কারণ আপনি পরবর্তী সংস্করণে কাজ শুরু করার সময় আপনার এখনও তাদের প্রয়োজন।
কিছু লোক যুক্তি দেখিয়েছেন যে আপনার কখনই দাবিগুলি ব্যবহার করা উচিত নয়, কারণ আপনি কখনই নিশ্চিত হতে পারবেন না যে সমস্ত বাগগুলি চলে গেছে, সুতরাং আপনার এগুলি এমনকি উত্পাদন পর্যন্ত রাখা উচিত to এবং সুতরাং দৃsert় বক্তব্যটি ব্যবহার করার কোনও অর্থ নেই, যেহেতু দাবি করার একমাত্র সুবিধা হ'ল আপনি সেগুলি বন্ধ করতে পারেন। অতএব, এই চিন্তাভাবনা অনুসারে, আপনার (প্রায়) কখনই আসক্তি ব্যবহার করা উচিত নয়। আমি একমত নই এটি অবশ্যই সত্য যে কোনও পরীক্ষা যদি উত্পাদনের সাথে সম্পর্কিত হয় তবে আপনার দৃ an়তা ব্যবহার করা উচিত নয়। কিন্তু এই পরীক্ষাটি করে না উৎপাদনে অন্তর্গত। এটি একটি এমন বাগটি ধরার জন্য যা সম্ভবত কখনও উত্পাদনে পৌঁছায় না, সুতরাং আপনার কাজ শেষ হয়ে গেলে এটি নিরাপদে বন্ধ হয়ে যেতে পারে।
বিটিডাব্লু, আমি এটি এইভাবে লিখতে পারতাম:
assert value == null || value.equals("Y") || value.equals("N") : value;
এটি কেবলমাত্র তিনটি মানের জন্য জরিমানা, তবে যদি সম্ভাব্য মানের সংখ্যা আরও বড় হয়, তবে হ্যাশসেট সংস্করণটি আরও সুবিধাজনক হবে। দক্ষতা সম্পর্কে আমার বক্তব্য রাখতে আমি হ্যাশসেট সংস্করণটি বেছে নিয়েছি।
HashSet
যদি কোনো ওভার কোনো গতি সুবিধা এনেছে ArrayList
। তদ্ব্যতীত, সেট এবং তালিকার ক্রিয়েশনগুলি লুকের সময়কে প্রাধান্য দেয়। ধ্রুবক ব্যবহার করার সময় তারা ভাল হয়ে যাবে। সব বলেছে, +1।
মূলত অ্যাপ্লিকেশনটি ডিবাগ করার জন্য দৃser়তা ব্যবহৃত হয় বা কোনও অ্যাপ্লিকেশনটির বৈধতা পরীক্ষা করতে কিছু অ্যাপ্লিকেশন ব্যতিক্রম হ্যান্ডলিংয়ের পরিবর্তে ব্যবহৃত হয়।
দৃser়তা রান সময় কাজ করে। একটি সাধারণ উদাহরণ, যা পুরো ধারণাটি খুব সহজভাবে ব্যাখ্যা করতে পারে, এখানে রয়েছে - জোড় শব্দক শব্দটি কী করে? (WikiAnswers)।
দাবিগুলি ডিফল্টরূপে অক্ষম থাকে। তাদের সক্ষম করতে আমাদের অবশ্যই -ea
বিকল্পগুলি সহ প্রোগ্রামটি চালাতে হবে (গ্রানুলারিটি বিভিন্ন রকম হতে পারে)। উদাহরণস্বরূপ java -ea AssertionsDemo
,।
আসক্তিগুলি ব্যবহারের জন্য দুটি ফর্ম্যাট রয়েছে:
assert 1==2; // This will raise an AssertionError
।assert 1==2: "no way.. 1 is not equal to 2";
এটি প্রদর্শিত বার্তাটি দিয়ে খুব বেশি উত্সাহ দেয় এবং এটি আরও ভাল। যদিও প্রকৃত সিনট্যাক্সটি assert expr1:expr2
সেখানে যেখানে expr2 কোনও মান ফেরত দেওয়া কোনও অভিব্যক্তি হতে পারে, আমি বার্তাটি মুদ্রণের জন্য এটি প্রায়শই ব্যবহার করেছি।পুনরুদ্ধার করতে (এবং এটি শুধুমাত্র জাভা নয় অনেক ভাষার ক্ষেত্রেই সত্য):
"দৃsert়তা" প্রাথমিকভাবে ডিবাগিং প্রক্রিয়া চলাকালীন সফ্টওয়্যার বিকাশকারীদের দ্বারা ডিবাগিং এইড হিসাবে ব্যবহৃত হয়। দাবী-বার্তা কখনও প্রদর্শিত হবে না। অনেক ভাষা একটি সংকলন-সময় বিকল্প সরবরাহ করে যা "উত্পাদন" কোড উত্পন্ন করার জন্য সমস্ত "দাবীগুলি" উপেক্ষা করে।
"ব্যতিক্রম" হ'ল সব ধরণের ত্রুটি শর্তগুলি পরিচালনা করার একটি সহজ উপায়, যদিও তারা যুক্তি ত্রুটির প্রতিনিধিত্ব করে বা না করে, কারণ, যদি আপনি কোনও ত্রুটি-শর্তে চালিয়ে যান যা আপনি চালিয়ে নিতে পারেন না, আপনি কেবল "এগুলি এয়ারে ফেলে দিতে পারেন, "আপনি যেখানেই থাকুন না কেন, অন্য কেউ তাদের" ধরা "দেওয়ার জন্য প্রস্তুত থাকার প্রত্যাশা করে। নিয়ন্ত্রণটি এক ধাপে স্থানান্তরিত হয়, সরাসরি কোডটি ব্যতিক্রম ছুঁড়ে দেওয়া থেকে সরাসরি ক্যাচারের মিটে স্থানান্তরিত হয়। (এবং ক্যাচারটি সংঘটিত কলগুলির পুরো ব্যাকট্রেস দেখতে পাবে))
তদুপরি, সেই সাবরুটিনের কলকারীদের সাব্রোটিন সফল হয়েছে কিনা তা পরীক্ষা করে দেখার দরকার নেই: "আমরা যদি এখন এখানে থাকি তবে এটি অবশ্যই সফল হত, কারণ অন্যথায় এটি একটি ব্যতিক্রম ছুঁড়ে ফেলেছে এবং আমরা এখন এখানে থাকতাম না!" এই সাধারণ কৌশলটি কোড-ডিজাইন এবং ডিবাগিংকে অনেক বেশি সহজ করে তোলে।
ব্যতিক্রমগুলি মারাত্মক-ত্রুটির শর্তগুলি সুবিধামত মঞ্জুরি দেয় যা তারা হ'ল: "নিয়মের ব্যতিক্রম" " এবং, তাদের জন্য কোনও কোড-পাথ পরিচালনা করা হবে যা "নিয়মের ব্যতিক্রম ... " বলের উড়ে! "
জোর দেওয়া চেক যা বন্ধ হতে পারে। এগুলি খুব কমই ব্যবহৃত হয়। কেন?
result != null
কারণ এ জাতীয় চেকগুলি খুব দ্রুত এবং সংরক্ষণ করার মতো খুব কমই কিছু আছে।তো, কী বাকি? অবস্থার জন্য ব্যয়বহুল চেকগুলি সত্য বলে আশা করা হচ্ছে । একটি ভাল উদাহরণ হ'ল আরবি-ট্রি এর মতো ডেটা স্ট্রাকচারের আক্রমণকারী। প্রকৃতপক্ষে, ConcurrentHashMap
জেডিকে 8-তে, এরকম কয়েকটি অর্থবহ আসক্তি রয়েছে TreeNodes
।
কখনও কখনও, চেকটি সত্যই ব্যয়বহুল নয় তবে একই সাথে আপনিও নিশ্চিত যে এটি পাস হয়ে যাবে। আমার কোডে, যেমন,
assert Sets.newHashSet(userIds).size() == userIds.size();
যেখানে আমি নিশ্চিত যে আমি সবে তৈরি করা তালিকার অনন্য উপাদান রয়েছে তবে আমি এটি নথিভুক্ত করে ডাবল চেক করতে চেয়েছিলাম।
মূলত, "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;
}
}
assert
একটি কীওয়ার্ড। এটি জেডিকে ২.৪ এ প্রবর্তিত হয়েছিল। দুটি ধরণের assert
এস
assert
বক্তব্যassert
বক্তব্য।ডিফল্টরূপে সমস্ত assert
বিবৃতি কার্যকর করা হবে না। যদি কোনও assert
বিবৃতি মিথ্যা পায় তবে তা স্বয়ংক্রিয়ভাবে একটি ত্রুটি উত্থাপন করবে।