জাভাতে কোডের একটি স্নিপেট তৈরি করা সম্ভব যা একটি অনুমানমূলক java.lang.ChuckNorrisException
অপ্রকাশ্য করতে পারে ?
মাথায় আসা চিন্তাগুলি উদাহরণস্বরূপ ইন্টারসেপ্টর বা দিক-ভিত্তিক প্রোগ্রামিংয়ের জন্য ব্যবহার করছে ।
finalize()
?
জাভাতে কোডের একটি স্নিপেট তৈরি করা সম্ভব যা একটি অনুমানমূলক java.lang.ChuckNorrisException
অপ্রকাশ্য করতে পারে ?
মাথায় আসা চিন্তাগুলি উদাহরণস্বরূপ ইন্টারসেপ্টর বা দিক-ভিত্তিক প্রোগ্রামিংয়ের জন্য ব্যবহার করছে ।
finalize()
?
উত্তর:
আমি এটি চেষ্টা করি নি, তাই আমি জানি না যে জেভিএম এর মতো কিছু সীমাবদ্ধ রাখবে কিনা , তবে আপনি হয়ত কোড সংকলন করতে পারেন যা নিক্ষেপ করে ChuckNorrisException
, তবে রানটাইমটিতে এমন একটি শ্রেণীর সংজ্ঞা প্রদান করে ChuckNorrisException
যা থ্রোয়েবলকে প্রসারিত করে না ।
হালনাগাদ:
এটি কাজ করে না। এটি একটি যাচাইকারী ত্রুটি উত্পন্ন করে:
Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow. Program will exit.
আপডেট 2:
আসলে, আপনি বাইট কোড ভেরিফায়ারটি অক্ষম করলে আপনি এটি কাজ করতে পারেন! ( -Xverify:none
)
আপডেট 3:
বাড়ি থেকে নিম্নলিখিতদের জন্য, এখানে সম্পূর্ণ স্ক্রিপ্ট:
নিম্নলিখিত ক্লাস তৈরি করুন:
public class ChuckNorrisException
extends RuntimeException // <- Comment out this line on second compilation
{
public ChuckNorrisException() { }
}
public class TestVillain {
public static void main(String[] args) {
try {
throw new ChuckNorrisException();
}
catch(Throwable t) {
System.out.println("Gotcha!");
}
finally {
System.out.println("The end.");
}
}
}
সংকলন ক্লাস:
javac -cp . TestVillain.java ChuckNorrisException.java
চালান:
java -cp . TestVillain
Gotcha!
The end.
"রানটাইম এক্সেপশন প্রসারিত করে" মন্তব্য করুন এবং কেবল পুনরায় কম্পাইল করুনChuckNorrisException.java
:
javac -cp . ChuckNorrisException.java
চালান:
java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain. Program will exit.
যাচাইকরণ ছাড়াই চালান:
java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"
Object
পরিবর্তে ধরেন Throwable
তবে কি? (সংকলক এটির অনুমতি দেয় না, তবে যেহেতু আমরা ইতিমধ্যে
এটি চিন্তা করার পরে, আমি সফলভাবে একটি অপ্রকাশনীয় ব্যতিক্রম তৈরি করেছি। আমি JulesWinnfield
চকের চেয়ে বরং এর নামকরণ বেছে নিয়েছি , কারণ এটি এক মাশরুম-মেঘ-পাড়ার-মা-ব্যতিক্রম। তদুপরি, আপনার মনে যেটি ছিল ঠিক তেমনটি নাও হতে পারে তবে এটি অবশ্যই ধরা যায় না। পালন:
public static class JulesWinnfield extends Exception
{
JulesWinnfield()
{
System.err.println("Say 'What' again! I dare you! I double dare you!");
System.exit(25-17); // And you shall know I am the LORD
}
}
public static void main(String[] args)
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
System.out.println("There's a word for that Jules - a bum");
}
}
এট ভয়েলা! অপ্রকাশিত ব্যতিক্রম।
আউটপুট:
সঞ্চালন করুন:
আবার 'কি' বলুন! আমি তোমাকে সাহস! আমি তোমাকে দ্বিগুণ সাহস করি!
জাভা ফলাফল: 8
বিল্ড সাফল্য (মোট সময়: 0 সেকেন্ড)
যখন আমার আরও কিছুটা সময় থাকবে, আমি দেখব যে আমি অন্য কিছু নিয়ে আসতে পারি না কিনা।
এছাড়াও, এটি পরীক্ষা করে দেখুন:
public static class JulesWinnfield extends Exception
{
JulesWinnfield() throws JulesWinnfield, VincentVega
{
throw new VincentVega();
}
}
public static class VincentVega extends Exception
{
VincentVega() throws JulesWinnfield, VincentVega
{
throw new JulesWinnfield();
}
}
public static void main(String[] args) throws VincentVega
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
}
catch(VincentVega vv)
{
}
}
স্ট্যাকের উপচে পড়ার কারণ - আবার, ব্যতিক্রমগুলি অবিরত রয়েছে।
JulesWinfield
? সিস্টেমটি ছোঁড়ার আগেই কি চিৎকার থামবে না?
throw new Whatever()
সত্যই দুটি অংশ: Whatever it = new Whatever(); throw it;
এবং সিস্টেমটি দ্বিতীয় অংশে পৌঁছানোর আগেই মারা যায়।
class cn extends exception{private cn(){}}
যেমন একটি ব্যতিক্রম সঙ্গে এটি অবশ্যই নির্মাতা থেকে একটি ব্যবহার বাধ্যতামূলক হবে System.exit(Integer.MIN_VALUE);
কারণ আপনি যদি এই ধরনের ব্যতিক্রম ছুঁড়ে ফেলেছিলেন তবে এটি ঘটবে;)
while(true){}
পরিবর্তে ব্যবহার করতে পারেন System.exit()
।
System.exit()
যা এটি অনুমোদিত নয় dis এটি নির্মাণকারীকে একটি ভিন্ন ব্যতিক্রম (সিকিউরিটি এক্সেপশন) হিসাবে রূপান্তরিত করবে, যা ধরা পড়তে পারে।
যে কোনও কোড থ্রোয়েবল ধরতে পারে। সুতরাং না, যাই হোক না কেন আপনি ব্যতিক্রমটি থ্রোয়েবলের একটি সাবক্লাস হতে চলেছেন এবং এটি ধরা পড়ার বিষয় হতে পারে।
hang
ধরার চেষ্টায় থ্রোয়েবল নিজেই চাইবে: পি
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
System.exit(1);
}
}
(মঞ্জুর, প্রযুক্তিগতভাবে এই ব্যতিক্রমটি আসলে কখনও ছুঁড়ে দেওয়া হয় না, তবে যথাযথভাবে ChuckNorrisException
নিক্ষেপ করা যায় না - এটি আপনাকে প্রথমে ছুড়ে দেয়))
আপনি যে কোনও ব্যতিক্রম নিক্ষেপ করলে থ্রোয়েবলকে প্রসারিত করতে হয়, তাই এটি সর্বদা ধরা যায়। সুতরাং উত্তর না হয়।
আপনি এটা কঠিন হ্যান্ডেল করতে চান, আপনি ওভাররাইড করতে পারে পদ্ধতি getCause(), getMessage()
, getStackTrace()
, toString()
অন্য নিক্ষেপ করা java.lang.ChuckNorrisException
।
catch(Throwable t)
এটি কেবলমাত্র পরিবর্তনশীল হিসাবে সংরক্ষণ করে তাই আমার পরামর্শগুলি কেবলমাত্র পরবর্তী ব্লকে তখনই প্রয়োগ হয় যখন ব্যবহারকারী ব্যতিক্রমগুলি মোকাবেলা করতে চান
আমার উত্তরটি @ জেতাহলবনের ধারণার ভিত্তিতে, তবে এটি সম্পূর্ণরূপে কাজ করা জাভা প্রোগ্রাম, এটি একটি জেআর ফাইলের মধ্যে প্যাকেজ করা যেতে পারে এবং এমনকি ওয়েব অ্যাপ্লিকেশনের অংশ হিসাবে আপনার প্রিয় অ্যাপ্লিকেশন সার্ভারে স্থাপন করা যেতে পারে ।
প্রথমত, আসুন ChuckNorrisException
ক্লাসটি সংজ্ঞায়িত করুন যাতে এটি শুরু থেকে জেভিএমকে ক্র্যাশ না করে (চক সত্যিই জেভিএম বিটিডাব্লু বিপর্যয় পছন্দ করে :)
package chuck;
import java.io.PrintStream;
import java.io.PrintWriter;
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
}
@Override
public Throwable getCause() {
return null;
}
@Override
public String getMessage() {
return toString();
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
}
}
Expendables
এটি নির্মাণে এখন ক্লাস চলে যায় :
package chuck;
import javassist.*;
public class Expendables {
private static Class clz;
public static ChuckNorrisException getChuck() {
try {
if (clz == null) {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("chuck.ChuckNorrisException");
cc.setSuperclass(pool.get("java.lang.Object"));
clz = cc.toClass();
}
return (ChuckNorrisException)clz.newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
এবং শেষ পর্যন্ত Main
কিছু বাট লাথি মারার ক্লাস:
package chuck;
public class Main {
public void roundhouseKick() throws Exception {
throw Expendables.getChuck();
}
public void foo() {
try {
roundhouseKick();
} catch (Throwable ex) {
System.out.println("Caught " + ex.toString());
}
}
public static void main(String[] args) {
try {
System.out.println("before");
new Main().foo();
System.out.println("after");
} finally {
System.out.println("finally");
}
}
}
নিম্নলিখিত কমান্ড দিয়ে এটি সঙ্কলন এবং চালনা:
java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main
আপনি নিম্নলিখিত আউটপুট পাবেন:
before
finally
অবাক হওয়ার কিছু নেই - এটি সর্বোপরি :)
না। জাভাতে সমস্ত ব্যতিক্রম অবশ্যই সাবক্লাসে আবশ্যক java.lang.Throwable
, এবং যদিও এটি ভাল অনুশীলন নাও হতে পারে তবে আপনি প্রতিটি ধরণের ব্যতিক্রমকে এভাবে ধরতে পারেন:
try {
//Stuff
} catch ( Throwable T ){
//Doesn't matter what it was, I caught it.
}
দেখুন java.lang.Throwable আরও তথ্যের জন্য ডকুমেন্টেশন।
আপনি যদি চেক করা ব্যতিক্রমগুলি এড়াতে চেষ্টা করছেন (যেগুলি অবশ্যই স্পষ্টভাবে পরিচালনা করতে হবে) তবে আপনি সাবক্লাস ত্রুটি বা রানটাইম এক্সসেপশনটি করতে চাইবেন।
প্রকৃতপক্ষে গৃহীত উত্তরটি এত সুন্দর নয় কারণ জাভা যাচাইকরণ ছাড়াই চালানো দরকার, অর্থাৎ কোডটি সাধারণ পরিস্থিতিতে কাজ করবে না।
আসল সমাধানের জন্য অ্যাসপেক্টজে উদ্ধার !
ব্যতিক্রম শ্রেণি:
package de.scrum_master.app;
public class ChuckNorrisException extends RuntimeException {
public ChuckNorrisException(String message) {
super(message);
}
}
অ্যাসপেক্ট:
package de.scrum_master.aspect;
import de.scrum_master.app.ChuckNorrisException;
public aspect ChuckNorrisAspect {
before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
throw chuck;
}
}
নমুনা প্রয়োগ:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
catchAllMethod();
}
private static void catchAllMethod() {
try {
exceptionThrowingMethod();
}
catch (Throwable t) {
System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
}
}
private static void exceptionThrowingMethod() {
throw new ChuckNorrisException("Catch me if you can!");
}
}
আউটপুট:
Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
at de.scrum_master.app.Application.main(Application.java:5)
থিমের বৈকল্পিকটি অবাক করা সত্য যে আপনি জাভা কোড থেকে অঘোষিত চেক করা ব্যতিক্রমগুলি ফেলে দিতে পারেন। যেহেতু এটি পদ্ধতিগুলির স্বাক্ষরে ঘোষণা করা হয়নি, সংকলকটি আপনাকে ব্যতিক্রম নিজেই ধরতে দেয় না, যদিও আপনি এটি জাভা.এলং.এক্সেপশন হিসাবে ধরতে পারেন।
এখানে একটি সহায়ক শ্রেণি যা আপনাকে কিছু ছুঁড়ে মারতে, ঘোষিত বা না করতে দেয়:
public class SneakyThrow {
public static RuntimeException sneak(Throwable t) {
throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
}
private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
throw (T) t;
}
}
এখন throw SneakyThrow.sneak(new ChuckNorrisException());
একটি ChuckNorrisException নিক্ষেপ করে না, তবে সংকলকটি এতে অভিযোগ করে
try {
throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}
চকনরিস এক্সসেপশন যদি চেক করা ব্যতিক্রম হয় তবে ছুঁড়ে দেওয়া হয় না এমন ব্যতিক্রম ধরা সম্পর্কে about
শুধুমাত্র ChuckNorrisException
জাভা গুলি হওয়া উচিত OutOfMemoryError
এবং StackOverflowError
।
আপনি প্রকৃতপক্ষে এগুলিকে "ধরা" দিতে পারেন যে catch(OutOfMemoryError ex)
ব্যতিক্রমটি ছুঁড়ে ফেলা হলে এটি কার্যকর করা হবে, তবে সেই ব্লকটি কলারের কাছে ব্যতিক্রমটি স্বয়ংক্রিয়ভাবে পুনর্বিবেচনা করবে।
আমি মনে করি public class ChuckNorrisError extends Error
না এটি কৌশলটি করে তবে আপনি এটি চেষ্টা করে দেখতে পারেন। আমি প্রসারিত করার বিষয়ে কোনও নথিপত্র পাইনিError
Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?
হ্যাঁ, এবং এখানে উত্তর: আপনার java.lang.ChuckNorrisException
এমন ডিজাইন করুন এটির উদাহরণ নয় java.lang.Throwable
। কেন? অবিশ্বাস্য অবজেক্টটি সংজ্ঞা অনুসারে অপ্রয়োজনীয় কারণ আপনি কখনও এমন কিছু ধরতে পারবেন না যা কখনও ছুঁড়ে দেওয়া যায় না।
java.lang.ChuckNorrisException
অবশ্যই একটি ব্যতিক্রম হতে হবে, একাকী হতে হবে
আপনি চকনরিসকে অভ্যন্তরীণ বা ব্যক্তিগত রাখতে পারেন এবং তাকে আবদ্ধ করতে পারেন বা তাকে গজিয়ে তোলা করতে পারেন ...
try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }
জাভাতে ব্যতিক্রম হ্যান্ডলিংয়ের সাথে দুটি মৌলিক সমস্যা হ'ল এটি ব্যতিক্রমের ধরণটি ব্যবহার করে তার উপর ভিত্তি করে ব্যবস্থা নেওয়া উচিত কিনা তা নির্দেশ করার জন্য এবং যে কোনও কিছু ব্যতিক্রমের ভিত্তিতে ব্যবস্থা গ্রহণ করে (যেমন "ধরা" এটি সমাধান করা হয়) অন্তর্নিহিত অবস্থা। কোনও উপায় রয়েছে যার মাধ্যমে কোনও ব্যতিক্রম বস্তু সিদ্ধান্ত নিতে পারে যে কোন হ্যান্ডলারের মৃত্যুদন্ড কার্যকর করা উচিত এবং যে হ্যান্ডলারগুলি এখনও অবধি সম্পাদন করেছে তা বর্তমান পদ্ধতির জন্য প্রস্থান শর্তগুলি পূরণ করার জন্য যথেষ্ট পরিমাণে জিনিস পরিষ্কার করেছে কিনা। যদিও এটি "অপ্রকাশনযোগ্য" ব্যতিক্রম করতে ব্যবহৃত হতে পারে, তার জন্য দুটি আরও বড় ব্যবহার ব্যতিক্রম (1) ব্যতিক্রম করা হবে যা কেবলমাত্র কোড দ্বারা ধরা পড়লে হ্যান্ডেল হিসাবে বিবেচিত হবে যা আসলে কীভাবে তাদের সাথে ডিল করতে হয় তা জানে,finally
FooException
একটি finally
আনওয়ানডিংয়ের সময় একটি ব্লকের সময় BarException
, উভয় ব্যতিক্রম কল কলকে প্রচার করতে হবে; উভয়ই ক্যাপচারযোগ্য হওয়া উচিত, তবে উভয়কে ধরা না পড়লে অযাচিত চলতে হবে)। দুর্ভাগ্যক্রমে, আমি মনে করি না যে কিছু ব্যতিক্রম না করে বিদ্যমান ব্যতিক্রম-পরিচালনা কোডটি সেভাবে কাজ করার কোনও উপায় থাকবে।
finally
ব্লক পূর্বের ব্যতিক্রমগুলি থেকে পরিষ্কার করার সময় যদি কোনও ব্যতিক্রম ঘটে থাকে তবে এটি সম্ভবত সম্ভব যে, ব্যতিক্রম অন্যটির অনুপস্থিতিতে, এমন কোনও কিছু হতে পারে যার কোডটি হ্যান্ডেল করার এবং চালিয়ে যাওয়ার প্রত্যাশা করবে, তবে এটি একটি পরিচালনা এবং অন্যটিকে উপেক্ষা করা খারাপ হবে। উভয় হ্যান্ডলারগুলি প্রক্রিয়া করবে এমন একটি যৌগিক ব্যতিক্রম উত্পাদন করার মতো কোনও ব্যবস্থা নেই।
Foo
একটি ব্যতিক্রমের মধ্যে পার্থক্য করতে পারে যা Foo
নিজেই ছুঁড়ে মারে বা ইচ্ছাকৃতভাবে নিজেকে ছুঁড়ে মারে এমন ভান করতে চায়, যা Foo
এমনটি হওয়ার আগে যখন এটি প্রত্যাশিত ছিল না অন্য কিছু পদ্ধতি কল করা। "পরীক্ষিত" ব্যতিক্রমগুলির ধারণাটি "সম্পর্কে" হওয়া উচিত।
বর্তমান থ্রেডে একটি অপ্রকাশিত ব্যতিক্রম অনুকরণ করা সহজেই সম্ভব। এটি একটি অনাবৃত ব্যতিক্রমের নিয়মিত আচরণকে ট্রিগার করবে এবং এভাবে শব্দার্থকভাবে কাজটি সম্পন্ন হবে। এটি অবশ্য বর্তমান থ্রেডের কার্যকর করা বন্ধ করবে না, কারণ কোনও ব্যতিক্রম আসলে নিক্ষেপ করা হয় না।
Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.
এটি প্রকৃতপক্ষে (খুব বিরল) পরিস্থিতিতে কার্যকর, উদাহরণস্বরূপ যখন সঠিক Error
পরিচালনা করার প্রয়োজন হয় তবে পদ্ধতিটি ফ্রেমওয়ার্ক থেকে যে কোনওটিকে ধরার (এবং ত্যাগ করা) থেকে নেওয়া হয় Throwable
।