কেন আমি আমার সুপার () কল কাছাকাছি একটি চেষ্টা ব্লক ব্যবহার করতে পারি না?

সুতরাং, জাভাতে, আপনার কন্সট্রাকটরের প্রথম লাইনটি একটি কল করার জন্য কল করা হয় ... এটি নিখুঁতভাবে সুপার() ডাকে, বা স্পষ্টভাবে অন্য কনস্ট্রাক্টরকে ডাকে। আমি কি জানতে চাই, কেন আমি এমন একটি চেষ্টা ব্লক করতে পারি না?

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

তাই, আমি কি করতে চাই তা হল এই:

public class MyClassMock extends MyClass {
    public MyClassMock() {
        try {
            super(0);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // Mocked methods
}

কিন্তু জাভা অভিযোগ করে যে সুপারটি প্রথম বিবৃতি নয়।

আমার সমাধান:

public class MyClassMock extends MyClass {
    public static MyClassMock construct() {
        try {
            return new MyClassMock();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public MyClassMock() throws Exception {
        super(0);
    }

    // Mocked methods
}

এটা কি সর্বোত্তম সমাধান? কেন জাভা না আগে আমাকে সাবেক?


আমার সবচেয়ে ভাল অনুমান "কেন" যে জাভা আমার একটি সম্ভাব্য অসঙ্গত রাষ্ট্র একটি নির্মাণ বস্তু যাক না চান ... তবে, একটি উপহাস করছেন, আমি যে সম্পর্কে যত্ন না। মনে হচ্ছে আমি উপরের কাজ করতে সক্ষম হওয়া উচিত ... অথবা কমপক্ষে আমি জানি যে উপরে আমার কেস জন্য নিরাপদ ... বা এটি যাই হোক না কেন হতে হবে মনে হয়।

আমি পরীক্ষিত বর্গ থেকে যে কোনও পদ্ধতি ব্যবহার করি, তাই আমি কোনও ঝুঁকি নেই যে আমি অনির্দিষ্ট ভেরিয়েবল ব্যবহার করছি।

0
ro fr hi
আপনি কি নিশ্চিত যে বাইটকোড এখনও বৈধ? আমি মনে করি এটি কারও কারও শোষিত হওয়ার ফলে অবৈধ হওয়াকে অমান্য করা হচ্ছে।
যোগ লেখক Joshua, উৎস
একটি আকর্ষণীয় নোট হল যে এটি সম্পূর্ণরূপে একটি জাভা ভাষা সীমাবদ্ধতা। সমমানের বাইটকোড পুরোপুরি বৈধ।
যোগ লেখক Antimony, উৎস
কারণ নিয়ম এটি অনুমোদিত নয়। JDK spec পড়ুন । এমনকি যদি আপনি কম্পাইলারটি শেষ করেন তবে যাচাইকারী এটি প্রত্যাখ্যান করবে।
যোগ লেখক Hot Licks, উৎস

7 উত্তর

আমি জাভা internals একটি গভীর বোঝার আছে presume করতে পারে না, কিন্তু এটা আমার বুদ্ধি যে, যখন একটি কম্পাইলার একটি উত্কীর্ণ ক্লাস instantiate প্রয়োজন, এটি প্রথম বেস (এবং তার আগে যে বেস (...) এবং তারপর subclass তৈরি এক্সটেনশন নেভিগেশন slap।

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

সম্পাদনা করুন: আপনার ক্ষেত্রে, MyClass মূল বস্তু হয়ে ওঠে এবং MyClassMock একটি উপকলা

0
যোগ

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

জাভা যদি কন্সট্রাকটর এ সুপার() কলের কাছাকাছি একটি চেষ্টা / ধরা দেয় তবে 1. যদি আপনি সুপারক্লাসগুলি থেকে সমস্ত পদ্ধতিগুলিকে ওভাররাইড করে দেন, এবং 2. আপনি সুপার ব্যবহার করেন না। XXX() ক্লোজ, তবে যে সমস্ত শব্দগুলি খুব জটিল আমাকে.

0
যোগ

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

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

C # .NET- তে অনুরূপ বিধান রয়েছে এবং একটি কনস্ট্রাক্টর ঘোষণা করার একমাত্র উপায় যা একটি বেস কন্সট্রাকটর কল করে:

public ClassName(...) : base(...)

এভাবে, বেস কন্সট্রাকটরকে কন্সট্রাকটরের শরীরের সামনে ডাকা হবে এবং আপনি এই অর্ডারটি পরিবর্তন করতে পারবেন না।

0
যোগ
কেন শুধু ক্যাচ ব্লকের এই ব্যবহার থেকে আপনাকে বাধা দেয়? যে মোড়ানো আপের সাধারণ কেস জুড়ে।
যোগ লেখক Antimony, উৎস

এটি একটি নতুন সিকিউরিটি ম্যানেজার অবজেক্ট কোড থেকে অবজেক্ট তৈরির থেকে রক্ষা করার জন্য এটি করা হয়েছে।

public class Evil : SecurityManager {
  Evil()
  {
      try {
         super();
      } catch { Throwable t }
      {
      }
   }
}
0
যোগ

এটির কাছাকাছি যাওয়ার একটি উপায় হল একটি ব্যক্তিগত স্ট্যাটিক ফাংশন কল করার মাধ্যমে। চেষ্টা-ধরা তারপর ফাংশন শরীরের মধ্যে স্থাপন করা যেতে পারে।

public class Test  {
  public Test()  {
     this(Test.getObjectThatMightThrowException());
  }
  public Test(Object o)  {
     //...
  }
  private static final Object getObjectThatMightThrowException()  {
     try  {
        return  new ObjectThatMightThrowAnException();
     }  catch(RuntimeException rtx)  {
        throw  new RuntimeException("It threw an exception!!!", rtx);
     }
  }
}
0
যোগ
আমি সামান্য বিট প্রসারিত। যথেষ্ট?
যোগ লেখক aliteralmind, উৎস
বিস্তারিত জানার জন্য যত্ন কেন?
যোগ লেখক Unheilig, উৎস
কেন একটি ব্যক্তিগত স্ট্যাটিক ফাংশন কল এখানে কাজ করে? ওপি দ্বারা কোডটি কি ভুল, যা আপনি মনে করেন না কাজ করে না?
যোগ লেখক Unheilig, উৎস
প্রশ্নটি উত্তরাধিকারসূত্রে প্রাপ্ত বিষয়ে জিজ্ঞাসা করা হয়েছে এবং এই কোডে এর পরিবর্তে রচনা আছে
যোগ লেখক Daniel Pinyol, উৎস

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

আমাকে অবজেক্ট নির্মাণ ব্যর্থতার একটি উদাহরণ দিয়ে শুরু করা যাক।

এর একটি ক্লাস A সংজ্ঞায়িত যাক, যেমন:

class A {
   private String a = "A";

   public A() throws Exception {
        throw new Exception();
   }
}

এখন, আসুন ধরুন আমরা একটি <�কোড> চেষ্টা ... ক্যাশ ব্লক টাইপ A এর বস্তু তৈরি করতে চাই।

A a = null;
try{
  a = new A();
}catch(Exception e) {
  //...
}
System.out.println(a);

স্পষ্টতই, এই কোডের আউটপুট হবে: null

কেন জাভা কোনও a এর আংশিকভাবে নির্মিত সংস্করণটি ফেরত পায় না? সব পরে, বিন্দু দ্বারা কন্সট্রাকটর ব্যর্থ হয়, বস্তুর <�কোড> নাম </কোড> ক্ষেত্র ইতিমধ্যেই শুরু করা হয়েছে, ঠিক আছে?

ওয়েল, জাভা একটি আংশিকভাবে A এর অবজেক্টের সংস্করণটি ফেরত দিতে পারে না কারণ বস্তু সফলভাবে তৈরি করা হয়নি। অবজেক্ট একটি অসঙ্গত অবস্থায় রয়েছে, এবং এটি জাভা দ্বারা বাতিল করা হয়। আপনার পরিবর্তনশীল A ​​এমনকি শুরু করা হয় না, এটি নাল হিসাবে রাখা হয়।

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

এই আরো বিস্তারিত উদাহরণ তাকান

class A {
   private final int a;
   public A() throws Exception { 
      a = 10;
   }
}

class B extends A {
   private final int b;
   public B() throws Exception {
       methodThatThrowsException(); 
       b = 20;
   }
}

class C extends B {
   public C() throws Exception { super(); }
}

B এর কন্সট্রাকটর চালু করা হলে, B আরম্ভ করার সময় কোনও ব্যতিক্রম ঘটে, তাহলে ফাইনালের int পরিবর্তনশীল এ?

যেমন, বস্তু C তৈরি করা যায় না, এটি বগাস, এটি আবর্জনা, এটি সম্পূর্ণরূপে আরম্ভ করা হয় না।

আমার জন্য, এই ব্যাখ্যাটি কেন আপনার কোডটি অবৈধ?

0
যোগ

আমি জানি এই প্রশ্নের অনেক উত্তর আছে, কিন্তু কেন আমি এই অনুমতি দেওয়া হবে না কেন আমার সামান্য tidbit দিতে চান, জাভা আপনি এই করতে অনুমতি দেয় না কেন বিশেষভাবে উত্তর। তাই এখানে আপনি যান ...

এখন, মনে রাখবেন যে সুপার() একটি উপকলা এর কন্সট্রাক্টর অন্য কিছু আগে বলা হবে, তাই, যদি আপনি ব্যবহার করে চেষ্টা করুন এবং catch আপনার <�কোড> সুপার() কলকে ব্লকগুলি ব্লকগুলিকে এটির মতো দেখতে হবে:

try {
   super();
   ...
} catch (Exception e) {
   super(); //This line will throw the same error...
   ...
}

যদি সুপার() ব্যর্থ হয় তাহলে চেষ্টা করুন ব্লকটি, প্রথমে ধরা যাক ব্লক, যাতে সুপার আগে আগে চালানো হয় আপনার উপকোষ কন্সট্রাকটরের মধ্যে কিছু এই আপনি শুরুতে ছিল একই সমস্যার সঙ্গে আপনি ছেড়ে: যদি একটি ব্যতিক্রম নিক্ষিপ্ত হয়, এটি ধরা হয় না। (এই ক্ষেত্রে এটি ক্যাচ ব্লকে আবারও নিক্ষিপ্ত হয়।)

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

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

0
যোগ