আমি জাভাতে স্থির নির্মাতাদের একটি সম্পূর্ণ উপলব্ধি পাইনি। যদি এটি অনুমোদিত হয় তবে কেন এটি অনুমোদিত? কোন পরিস্থিতিতে আপনি এটি ব্যবহার করবেন? এটি কোন উদ্দেশ্যে কাজ করবে? কেউ আমাকে একটি সহজ উদাহরণ দিতে পারেন দয়া করে?
আমি জাভাতে স্থির নির্মাতাদের একটি সম্পূর্ণ উপলব্ধি পাইনি। যদি এটি অনুমোদিত হয় তবে কেন এটি অনুমোদিত? কোন পরিস্থিতিতে আপনি এটি ব্যবহার করবেন? এটি কোন উদ্দেশ্যে কাজ করবে? কেউ আমাকে একটি সহজ উদাহরণ দিতে পারেন দয়া করে?
উত্তর:
কড়া কথায় বলতে গেলে জাভাতে স্ট্যাটিক কনস্ট্রাক্টর নেই কারণ সংজ্ঞা অনুসারে কোনও কনস্ট্রাক্টর স্থির থাকতে পারে না । আপনি যা উল্লেখ করছেন তাকে "স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লক" বলা হয়। একটি কনস্ট্রাক্টর বোঝায় যে আপনি কোনও অবজেক্ট তৈরি করছেন। আপনার কোনও ক্লাসের জন্য কনস্ট্রাক্টর থাকতে পারে না কারণ কোনও শ্রেণি নিজেই একটি উদাহরণ নয়। এটি কেবল একটি শ্রেণি। ক্লাসটি "কনস্ট্রাক্ট" করে তাকে কম্পাইলার (বা ভার্চুয়াল মেশিন, "কনস্ট্রাক্টস" বলতে বোঝানো হয়েছে তার উপর নির্ভর করে) এবং যদি আপনি অন্য কোডের মধ্যে কোড তৈরি করতে যান তবে আপনি কোড তৈরি করছেন যা হ'ল একটি সম্পূর্ণ ভিন্ন প্রাণী।
সমস্ত নিট-পিকিং একদিকে রেখে, একটি স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লক একটি ক্লাসের জন্য জটিল স্ট্যাটিক (বা শ্রেণি-স্তর) ক্ষেত্রকে আরম্ভ করতে ব্যবহৃত হয়। সাধারণত এগুলি এমন জিনিসগুলিকে আরম্ভ করার জন্য ব্যবহৃত হয় যা হয় এক লাইনে আরম্ভ করা যায় না, বা প্রয়োজন হয় যে অন্য কোনও অবজেক্ট (যা ক্লাসে থাকতে পারে বা স্ট্যাটিক ব্লকটি প্রয়োগ করা হয়) প্রথমে শুরু করা উচিত।
মূলত, ক্লাসটি বলতে কেউ তাদের ব্যবহার করতে পারে "আরে, এই মানটি প্রথমে ভেরিয়েবল এ সেট করুন, তারপরে, এটি শেষ হয়ে গেলে, বি এর সূচনা করতে A এর মান ব্যবহার করুন" " যেহেতু জাভাটির প্রয়োজন হয় যে স্ট্যান্ডার্ড ক্ষেত্রের সূচনাটি কোনও নির্মাণকারী বা পদ্ধতির মধ্যেই করা যেতে পারে, বা কোনও নির্মাণকারী বা পদ্ধতির কলের মাধ্যমে (এটি আক্ষরিক না হলে), জটিলগুলি, স্ট্যাটিক অবজেক্টগুলিকে সূচনা করার জন্য এগুলি একটি সুবিধাজনক পদ্ধতি হতে পারে।
স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লকগুলি প্রায়শই খুব বেশি প্রয়োজন হয় না এবং তাদের সত্যিকারের ব্যবহার না হলে সাধারণত এড়ানো উচিত । আমাকে ভুল করবেন না, জাভাতে তাদের জায়গা রয়েছে তবে অন্যান্য অনেক কিছুর মতো (যেমন বিরতি, রিটার্ন, স্যুইচ এবং গোটো স্টেটমেন্ট) এগুলি খুব বেশি ব্যবহার করা যেতে পারে, যা তাদের পাঠযোগ্যতা এবং কোডের রক্ষণাবেক্ষণকে হ্রাস করে -বুসে তারা ব্যবহৃত হয়।
একটি স্ট্যাটিক আরম্ভের ব্লক একটি সংক্ষিপ্ত উদাহরণ ব্যবহার করা হচ্ছে নিম্নলিখিত (প্রতি যেমন হবে চমৎকার স্ট্যাটিক আরম্ভের ব্লক ব্যাখ্যা পাওয়া এখানে ):
কোড:
public class StaticExample{
static {
System.out.println("This is first static block");
}
public StaticExample(){
System.out.println("This is constructor");
}
public static String staticString = "Static Variable";
static {
System.out.println("This is second static block and "
+ staticString);
}
public static void main(String[] args){
StaticExample statEx = new StaticExample();
StaticExample.staticMethod2();
}
static {
staticMethod();
System.out.println("This is third static block");
}
public static void staticMethod() {
System.out.println("This is static method");
}
public static void staticMethod2() {
System.out.println("This is static method2");
}
}
আউটপুট:
This is first static block
This is second static block and Static Variable
This is static method
This is third static block
This is constructor
This is static method2
স্ট্যাটিক ব্লকগুলি কার্যকর হতে পারে যখন সেগুলি তালিকাভুক্ত করে:
স্ট্যাটিক ব্লক (অন্যান্য পরিস্থিতিতে) ব্যবহার না করার কয়েকটি কারণ:
this
কোনও উদাহরণ না থাকায় আপনি কীওয়ার্ডটি ব্যবহার করতে পারবেন না ।আমার মনে রাখা উচিত: কিছু ভাষায় (যেমন সি #) স্থির "কন্সট্রাক্টর" এর সিনট্যাক্স থাকতে পারে, সেই "কনস্ট্রাক্টর" জাভাতে ঠিক একইভাবে কাজ করে এবং অনেকগুলি (আমার অন্তর্ভুক্ত) হিসাবে দেখা হয় একটি ওওপি নির্মাণকারীর প্রাথমিক ধারণাটি দেওয়া, ভাষায় ভুল ব্যবহারকারী ।
এটি ক্ষেত্রগুলি সূচনা করতে ব্যবহার করা হয় যা কেবলমাত্র নির্ধারণের চেয়ে আরও শক্ত:
public class Example{
public final static Map<String, String> preFilledField;
static{
Map<String, String> tmp = new HashMap<>();
//fill map
preFilledField = Collections.unmodifiableMap(tmp);
}
}
শুরুতে কোনও মানচিত্র পূরণ করা সম্ভব নয় (যদি আপনি বেনামে সাবক্লাস হ্যাক ব্যবহার না করেন) তবে এটি ব্যবহারের আগে এটি পূরণ করার গ্যারান্টি দেওয়ার সর্বোত্তম উপায় is
আরম্ভ করার সময় আপনি পরীক্ষিত ব্যতিক্রমগুলি ধরতে এটিও করতে পারেন
গুরগডুর্গেনের উত্তর সম্ভবত আপনি যা খুঁজছেন তা হ'ল, তবে আমি যখন কেবলমাত্র "স্ট্যাটিক কনস্ট্রাক্টর" চাইলে কখনও কখনও অবহেলা করা হয় এমন কয়েকটি অন্যান্য পয়েন্ট যুক্ত করব।
আপনি যদি কোনও স্ট্যাটিক পদ্ধতি চান যা আপনার শ্রেণীর উদাহরণ তৈরি করে, আপনি একটি স্ট্যাটিক পদ্ধতি তৈরি করতে পারেন যা ক্লাসের নির্মাতাকে কেবল অনুরোধ করে।
public class Example
{
/** Static method to create an instance. */
public static Example build()
{ return new Example() ; }
/** A field of each instance. */
private String stuff ;
/** The class's actual constructor. */
public Example()
{ stuff = new String() ; }
public String getStuff()
{ return this.stuff ; }
/**
* Mutator for "stuff" property. By convention this returns "void"
* but you might want to return the object itself, to support the
* sort of chained invocations that are becoming trendy now. You'll
* see the stylistic benefits of chaining later in this example.
*/
public Example setStuff( String newStuff )
{
this.stuff = newStuff ;
return this ;
}
}
public class ExampleTest
{
public static void main( String[] args )
{
// The usual instance model.
Example first = new Example() ;
System.out.println( first.setStuff("stuff").getStuff() ) ;
// Using your static method to construct an instance:
Example second = Example.build() ;
System.out.println( second.setStuff("more stuff").getStuff() ) ;
// Chaining all the invocations at once:
System.out.println( Example.build().setStuff("even more stuff").getStuff() ) ;
}
}
এটি আউটপুট উত্পাদন করে:
stuff
more stuff
even more stuff
কোনও পরিস্থিতি তৈরির জন্য স্থিতিশীল পদ্ধতি তৈরি করার অন্য কারণটি হ'ল আপনি যখন নিশ্চিত করতে চান যে আপনার শ্রেণীর ঠিক একটি উদাহরণ কোনও নির্দিষ্ট সময়ে বিদ্যমান; একে সিঙ্গলটন বলা হয় । কনভেনশন অনুসারে, এই জাতীয় শ্রেণি একটি স্থিতিশীল পদ্ধতি সরবরাহ করবে যা ডাকে একটি এবং একমাত্র উদাহরণ যা "সিঙ্গলটন" হিসাবে বিবেচিত getInstance()
হয় get
public class SingletonExample extends Example
{
// Note: This extends my previous example, which has a "stuff"
// property, and a trivial constructor.
/** The singleton instance, statically initialized as null. */
private static SingletonExample singleton = null ;
/**
* The static accessor for the singleton. If no instance exists,
* then it will be created; otherwise, the one that already exists
* will be returned.
*/
public static SingletonExample getInstance()
{
if( singleton == null )
singleton = new SingletonExample() ;
return singleton ;
}
}
public class SingletonExampleTest
{
public static void main( String[] args )
{
System.out.println( SingletonExample.getInstance().setStuff("stuff").getStuff() ) ;
// You could still create instances of this class normally if you want to.
SingletonExample otherstuff = new SingletonExample() ;
otherstuff.setStuff("other stuff") ;
// But watch what happens to this.
System.out.println( SingletonExample.getInstance().getStuff() ) ;
System.out.println( otherstuff.getStuff() ) ;
// Now we show what happens when you start modifying the singleton.
SingletonExample theoneandonly = SingletonExample.getInstance() ;
theoneandonly.setStuff("changed stuff") ;
System.out.println( SingletonExample.getInstance().getStuff() ) ;
}
}
এটি নিম্নলিখিত উত্পাদন করে।
stuff
stuff
other stuff
changed stuff
সিঙ্গেলটনে একটি রেফারেন্স সঞ্চয় করে এবং তারপরে এটি সংশোধন করে, পরবর্তী কলটি getInstance()
সেই সংশোধিত সিঙ্গেলটন পায়।
আপনার আবেদনের জন্য বৈশ্বিক ভেরিয়েবল তৈরি শুরু করার উপায় হিসাবে সিঙ্গলেটগুলি ব্যবহার করার জন্য এটি লোভনীয়। কিছু প্রসঙ্গে এটি কার্যকর হতে পারে তবে এটি আপনাকে সমস্যায় ফেলতে পারে। বিশেষত আমি একটি অ্যান্ড্রয়েড অ্যাপ্লিকেশন বিকাশের সময় একটি আকর্ষণীয় বাগে চলে এসেছি, যেখানে সিঙ্গলটন উদাহরণ হারিয়ে যেতে পারে। এক ক্রিয়াকলাপ থেকে অন্য ক্রিয়াকলাপে ঝাঁপিয়ে পড়া কখনও কখনও জেভিএমকে একটি নতুন "শ্রেণি লোডার" ব্যবহার করতে পরিচালিত করতে পারে যা পূর্ববর্তী শ্রেণীর লোডার দ্বারা স্থায়ীভাবে সংরক্ষণ করা সিঙ্গলটন সম্পর্কে জানতে পারে না।
যদিও আমি বুঝতে পেরেছি যে অনেকেই "স্ট্যাটিক কনস্ট্রাক্টর" এর ধারণাটি ভুল ধারণা হিসাবে দেখেন, আমি বিশ্বাস করি না যে এটি হবে। ইস্যুটি উভয় শ্রেণি এবং তাদের উদাহরণ বস্তুগুলি নির্মাণের প্রক্রিয়াধীন । অন্যান্য থ্রেডে এটি বলা হয়েছে যে ক্লাস নির্মাণ করা সংকলকের কাজ। এমনকি জাভাতেও এটি অর্ধেক সত্য।
সংকলক প্রতিটি শ্রেণীর সংজ্ঞার জন্য একটি ভাস্কর্য তৈরি করে। স্ক্যাফোল্ডটিতে বর্গ সম্পর্কে মেটাডেটা রয়েছে এবং নির্মাণের সময় তাদের মধ্যে কী উদাহরণ থাকতে হবে। কোনও শ্রেণি যদি এমন একটি ক্ষেত্র নির্ধারণ করে যা ধ্রুবক আদিম মান নির্ধারিত হয়, তবে সেই মানটি সংকলক দ্বারা স্ক্যাফোর্ডে অন্তর্ভুক্ত করা হবে। নির্ধারিত অন্য কোনও মান ধরণের জন্য, সংকলক প্রথম শ্রেণীর উদাহরণ তৈরির আগে 1 বার চালানো একটি আর্টিনাইজেশন রুটিন উত্পন্ন করে, যা সঠিক মানগুলির সাথে স্ক্যাফলটিকে আপডেট করে। সংকলক দ্বারা এই আপডেট করা যাবে না।
যেহেতু স্ক্যাফোলে এই ওয়ান-টাইম আপডেটটি প্রায়শই ইনস্ট্যান্ট কনস্ট্রাক্টরগুলির সঠিক ক্রিয়াকলাপের জন্য একটি সমালোচনামূলক পূর্বশর্ত, তাই একে একে এক ধরণের কনস্ট্রাক্টর বলাও যুক্তিসঙ্গত। এই কারণেই ধারণাটিকে সমর্থনকারী সাধারণ ওও ভাষাগুলিতে এটিকে একটি স্ট্যাটিক কনস্ট্রাক্টর বলা হয়। জাভা স্থিতিশীল ব্লকগুলির পিছনে ধারণাটি জাভা প্রোগ্রামার সিস্টেম এবং বাস্তবায়ন অজ্ঞেয়াদিক উভয়ই হওয়া উচিত এই ধারণার সাথে সামঞ্জস্য রেখে অর্থবহ পরিবর্তনের চেয়ে কিছুটা বেশি।
অন্যান্য উত্তর যেমন বলেছে, আপনি স্থির পদ্ধতি লিখতে পারেন যা কোনও অবজেক্ট তৈরি করে। এটি জাভাতে নামকরণকারী কন্সট্রাক্টরের অভাবকে ঘিরে ফেলেছে (এবং আরও অনেক ভাষায় Del আপনি পরামিতিগুলির ধরণ এবং ক্রম দিয়ে খেলতে পারেন তবে এটি অস্পষ্ট এবং ভঙ্গুর কোডের দিকে নিয়ে যেতে পারে।
উদাহরণস্বরূপ, আমরা এমন একটি দৃশ্য আবিষ্কার করতে পারি যেখানে কোনও এক্সএমএল স্ট্রিং বা জেএসএন স্ট্রিং থেকে আপনার অবজেক্ট তৈরি করা যায়। আপনি যেমন পদ্ধতি লিখতে পারেন:
static MyObject createFromXml(String xml);
static MyObject createFromJson(String json);
নামকরণকৃত সূচনা পদ্ধতির সাথে প্যারামিটারলেস কনস্ট্রাক্টরের বিকল্প হিসাবে আমি এটি খুব মাঝে মাঝে ব্যবহার করেছি:
MyObject myObject = new MyObject();
myObject.loadXml(xml).
আপনি আপনার শ্রেণীর অভ্যন্তরে বিল্ডার প্যাটার্ন বাস্তবায়ন হিসাবে একটি স্থির তৈরি পদ্ধতির দিকে নজর রাখতে পারেন।
শ্রেণীর বৈশিষ্ট্য (জাভাতে স্থির) আরম্ভ করার জন্য আপনি কোনও শ্রেণি স্তরের নির্মাণকারীর ব্যবহারের মতো "স্ট্যাটিক" বিভাগটি দেখতে পারেন। উদাহরণস্বরূপ স্তরের বৈশিষ্ট্য আরম্ভ করার জন্য এটি ব্যবহৃত "সাধারণ" কনস্ট্রাক্টরের সমান।