স্থির সূচনা ব্লক


265

আমি যতদূর বুঝতে পেরেছি "স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লক" স্ট্যাটিক ফিল্ডের মান সেট করতে ব্যবহৃত হয় যদি এটি এক লাইনে না করা যায়।

তবে কেন আমাদের এটির জন্য একটি বিশেষ ব্লক প্রয়োজন তা আমি বুঝতে পারি না। উদাহরণস্বরূপ আমরা একটি ক্ষেত্রকে স্থির হিসাবে ঘোষণা করি (মান নির্ধারণ ছাড়া)। এবং তারপরে কোডটির বেশ কয়েকটি লাইন লিখুন যা উপরের ঘোষিত স্থিতিশীল ক্ষেত্রে একটি মান উত্পন্ন করে এবং নির্ধারণ করে।

: কেন আমরা মত একটি বিশেষ ব্লক এ এই লাইন দরকার static {...}?


6
গৌণ প্রতিক্রিয়া, তবে আপনি যদি আপনার অনুমানগুলি পরিষ্কারভাবে বর্ণনা করতে পারেন তবে এটির সাহায্য করবে এবং কোন উত্তরটি সঠিক তা স্পষ্ট করে। যখন আমি প্রথম আপনার প্রশ্নের পড়া, আমি ভুল বোঝা যায় এবং ভেবেছিলাম তুমি মধ্যে পার্থক্য জানত {...}বনাম static {...}। (এই ক্ষেত্রে জোন স্কিটি আপনার প্রশ্নের উত্তর অবশ্যই ভাল দিয়েছিল)
ডেভিড টি।

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

উত্তর:


430

অ স্ট্যাটিক ব্লক:

{
    // Do Something...
}

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

উদাহরণ:

public class Test {

    static{
        System.out.println("Static");
    }

    {
        System.out.println("Non-static block");
    }

    public static void main(String[] args) {
        Test t = new Test();
        Test t2 = new Test();
    }
}

এই মুদ্রণ:

Static
Non-static block
Non-static block

106
কেন এটি গৃহীত উত্তর? এমনকি প্রশ্নের উত্তরও দেয় না।
পল বেলোরা

43
এটি প্রশ্নের উত্তর দেয়: "ক্লাসটি তৈরি হওয়ার সময় এটি প্রতিবারই ডেকে আনে you স্ট্যাটিক ব্লকটি কেবল একবার কল হয়ে যায়, আপনি যে ধরণের কতগুলি অবজেক্ট তৈরি করেন তা নির্বিশেষে।"
অ্যাডাম আর্ল্ড

83
কৌতূহলী পাঠকের জন্য, অ স্থিতিক ব্লকটি আসলে জাভা সংকলক দ্বারা বর্গের প্রতিটি উত্সে ( উত্স ) অনুলিপি করা হয়েছে । সুতরাং ক্ষেত্রগুলি আরম্ভ করার জন্য এটি এখনও নির্মাণকারীর কাজ।
মার্টিন অ্যান্ডারসন

2
গৃহীত উত্তরটি এটির একটি হওয়া উচিত: stackoverflow.com/a/2420404/363573 । এই উত্তরটি বাস্তব জীবনের উদাহরণ উপস্থাপন করে যেখানে আপনার স্ট্যাটিক ব্লক প্রয়োজন।
স্টেফান

16
কেন এই উত্তর হঠাৎ হ্রাস করা হচ্ছে? আপনি এটি গ্রহণযোগ্য উত্তর হওয়া সম্পর্কে দ্বিমত পোষণ করতে পারেন তবে এটি অবশ্যই কোনওভাবেই ভুল বা বিভ্রান্তিমূলক নয়। এটি সরল উদাহরণ সহ এই ভাষা নির্মাণগুলি বোঝার জন্য সহজভাবে চেষ্টা করছে।
ফ্রেডেরিক ওয়ার্ডেনস্কোल्ड

132

যদি তারা কোনও স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লকে না থাকে তবে তারা কোথায় থাকত? আপনি কীভাবে এমন একটি পরিবর্তনশীল ঘোষণা করবেন যা কেবলমাত্র আরম্ভের উদ্দেশ্যে স্থানীয় হওয়ার উদ্দেশ্যে বোঝানো হয়েছিল এবং ক্ষেত্র থেকে আলাদা করতে পারত? উদাহরণস্বরূপ, কিভাবে হবে আপনি লিখতে চান:

public class Foo {
    private static final int widgets;

    static {
        int first = Widgets.getFirstCount();
        int second = Widgets.getSecondCount();
        // Imagine more complex logic here which really used first/second
        widgets = first + second;
    }
}

যদি firstএবং secondকোনও ব্লক না থাকত তবে তারা ক্ষেত্রগুলির মতো দেখতে চাইবে। যদি তারা staticএর সামনে না থাকলে কোনও ব্লকে থাকে, এটি স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লকের পরিবর্তে উদাহরণস্বরূপ ব্লক হিসাবে গণনা করা হত, সুতরাং এটি মোট একবারে না হয়ে একবার প্রতি নির্মাণের জন্য একবার কার্যকর করা হবে ।

এখন এই বিশেষ ক্ষেত্রে, আপনি পরিবর্তে একটি স্থিতিশীল পদ্ধতি ব্যবহার করতে পারেন:

public class Foo {
    private static final int widgets = getWidgets();

    static int getWidgets() {
        int first = Widgets.getFirstCount();
        int second = Widgets.getSecondCount();
        // Imagine more complex logic here which really used first/second
        return first + second;
    }
}

... তবে যখন একই ব্লকের মধ্যে আপনি একাধিক ভেরিয়েবল বরাদ্দ করতে চান তবে তা কার্যকর হয় না বা কোনও কিছুই নয় (যেমন আপনি যদি কিছু লগ করতে চান - অথবা কোনও স্থানীয় গ্রন্থাগার শুরু করতে পারেন)।


1
স্ট্যাটিক ব্লকটি স্ট্যাটিক ভেরিয়েবলগুলি নির্ধারিত হওয়ার আগে বা পরে সংঘটিত হয়? private static int widgets = 0; static{widgets = 2;}
ওয়েশি জেং

1
স্ট্যাটিক ভেরিয়েবলগুলি নির্ধারিত হওয়ার আগে বা তার আগে স্ট্যাটিক ব্লক ঘটে কিনা তা নিয়ে কৌতূহল ছিল। যেমন private static int widgets = 0; static{widgets = 2;}খুঁজে পেয়েছি যে '=' অ্যাসাইনমেন্টটি ক্রমানুসারে ঘটে, যার অর্থ '=' রাখার আগে প্রথমে নিয়োগ দেওয়া হবে। উপরের উদাহরণটি 'উইজেটগুলিকে' 2 এর মান দেবে (পিএস জানেন না যে মন্তব্যগুলি কেবল 5 মিনিটে সম্পাদনা করা যায় ...)
ওয়েশি জেনগ

@ ওয়েশিজেং: হ্যাঁ, এটি ডকস.অরাকল.com/ জাভাসে / স্পেসস / জেলস / এসএইচ / এমএইচটিএমএল - 9 পয়েন্টে যেমনটি নথিভুক্ত হয়েছে
জন স্কিটি

তবে আপনি কী কোনও প্রাইভেট স্ট্যাটিক পদ্ধতি ব্যবহার করতে পারবেন না যা স্থির সূচনা ব্লকের মতো সঠিক কোড রয়েছে এবং ব্যক্তিগত স্ট্যাটিক পদ্ধতিতে উইজেটগুলি নির্ধারণ করতে পারে?
জাচারি ক্রাউস

1
@ জাচারি: আপনার মানে কী মূল্য ফেরানো, এবং পদ্ধতি কলের ফলাফল নির্ধারণ করা? যদি তাই হয়, হ্যাঁ - যখন আপনি হয় ব্লক ফলে ঠিক একটি পরিবর্তনশীল বরাদ্দ। আমার উত্তরটি প্রায় 7 ঘন্টার মধ্যে বিশদ সহ সম্পাদনা করবে ...
জন স্কিটি

103

এখানে একটি উদাহরণ:

  private static final HashMap<String, String> MAP = new HashMap<String, String>();
  static {
    MAP.put("banana", "honey");
    MAP.put("peanut butter", "jelly");
    MAP.put("rice", "beans");
  }

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

অ-স্ট্যাটিক ইনিশিয়ালাইজার ব্লক থাকাও সম্ভব। যারা শ্রেণীর জন্য নির্ধারিত কনস্ট্রাক্টর পদ্ধতির সেটকে বাড়ানোর মতো কাজ করে। "স্ট্যাটিক" কীওয়ার্ডটি বাদ না রেখে এগুলি দেখতে স্ট্যাটিক ইনিশিয়ালাইজার ব্লকের মতো দেখতে লাগে।


4
সেই নির্দিষ্ট উদাহরণের জন্য কখনও কখনও ডাবল ব্রেস প্যাটার্নটিকে "
আপত্তিজনক

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

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

আমরা কি প্রপার্টিসেট পদ্ধতির পরে আরিনালাইজিংবিয়ান ব্যবহার করে এটি করতে পারি?
এজেনিয়ান

48

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

যেমন

static {
    try {
        Class.forName("com.example.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        throw new ExceptionInInitializerError("Cannot load JDBC driver.", e);
    }
}

আরে, আরও একটি সুবিধা রয়েছে, আপনি ব্যতিক্রমগুলি পরিচালনা করতে এটি ব্যবহার করতে পারেন। কল্পনা করুন যে, getStuff()এখানে একটি ছোঁড়ার Exceptionযা সত্যিকার অর্থে ক্যাচ ব্লকে অন্তর্ভুক্ত:

private static Object stuff = getStuff(); // Won't compile: unhandled exception.

তারপরে একটি staticইনিশিয়ালাইজার এখানে দরকারী। আপনি সেখানে ব্যতিক্রম পরিচালনা করতে পারেন।

আরেকটি উদাহরণ হ'ল পরে জিনিসগুলি করা যা যা প্রদানের সময় করা যায় না:

private static Properties config = new Properties();

static {
    try { 
        config.load(Thread.currentThread().getClassLoader().getResourceAsStream("config.properties");
    } catch (IOException e) {
        throw new ExceptionInInitializerError("Cannot load properties file.", e);
    }
}

জেডিবিসি ড্রাইভারের উদাহরণে ফিরে আসার জন্য, যে কোনও শালীন জেডিবিসি ড্রাইভার নিজে নিজেই নিজেকে আরজিস্টারে staticরেজিস্ট্রেশন করতে ইনিশিয়ালাইজারটি ব্যবহার করে DriverManager। আরো দেখুন এই এবং এই উত্তর।


2
এর মধ্যে রয়েছে বিপজ্জনক ভুডু ... স্ট্যাটিক ইনিশিয়ালাইজারগুলি সিন্থেটিক ক্লিনিট () পদ্ধতিতে চালিত হয় যা সুস্পষ্টভাবে সিঙ্ক্রোনাইজ করা হয় । এর অর্থ জেভিএম প্রশ্নযুক্ত ক্লাসফাইলে একটি লক অর্জন করবে। এটি যদি দুটি শ্রেণি একে অপরকে লোড করার চেষ্টা করে এবং প্রতিটি প্রত্যেকে আলাদা আলাদা থ্রেডে লোড করা শুরু করে তবে এটি মাল্টিথ্রেডেড পরিবেশে অচলাবস্থার সৃষ্টি করতে পারে। দেখুন www-01.ibm.com/support/docview.wss?uid=swg1IV48872
আয়াক্স

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

এটি অবশ্যই একটি বাগ হবে তবে পুরোপুরি জেডিবিসি ড্রাইভারের দোষ নয়। হতে পারে ড্রাইভারের নির্দোষভাবে নিজস্ব স্ট্যাটিক ইনিশিয়েলজার রয়েছে এবং সম্ভবত আপনি আপনার অ্যাপে থাকা অন্য কয়েকজনকে সাথে নিয়ে এই ক্লাসটি নির্দোষভাবে শুরু করেছিলেন এবং ওহ না, কিছু অপ্রত্যাশিত ক্লাস চক্রাকারে একে অপরকে লোড করে এবং এখন আপনার অ্যাপ্লিকেশনটি অচল করে দিয়েছে। Java.awt.AWTEvent এবং sun.util.logging.PlatformLogger এর মধ্যে অচলাবস্থার জন্য আমি এই ধন্যবাদটি আবিষ্কার করেছি। আমি কেবল মাথা উঁচু করে চালানোর জন্য এটি ডাব্লুটিইউইভেন্টকে স্পর্শ করেছি এবং প্ল্যাটফর্মলগার লোড করার ফলে অন্য কিছু লিব ক্ষতবিক্ষত করেছে ... যা এডব্লিউটিভেন্টও লোড করে।
আজাক্স

1
উভয় ক্লাসই বিভিন্ন থ্রেডে সিঙ্ক্রোনাইজ হয়ে গেছে এবং আমার বিল্ডটি প্রায় ১/১৫০ রান অচল করে দিয়েছে। সুতরাং, আমি এখন স্ট্যাটিক ব্লকগুলিতে শ্রেণিবদ্ধকরণ সম্পর্কে অনেক বেশি সতর্ক am আমি উপরে উল্লিখিত ক্ষেত্রে, একটি স্থগিত সরবরাহকারী প্যাটার্ন ব্যবহার করে যেখানে আমি অবিলম্বে একটি অন্তর্বর্তী প্রদানকারী শ্রেণি তৈরি করতে পারতাম (অচলাবস্থার কোনও সম্ভাবনা ছাড়াই), ক্ষেত্রটি আরম্ভ করতে পারি এবং তারপরে যখন এটি আসলে অ্যাক্সেস হয় (অ-সিঙ্ক্রোনাইজড ফিল্ড অ্যাক্সেসে), তখন আমি আসলে ক্লাসগুলি লোড করি যা অচলাবস্থার কারণ হতে পারে।
আজাক্স

11

আমি বলব static blockযে কেবল সিনট্যাকটিক চিনি। staticব্লকের সাথে আপনি করতে পারার মতো কিছুই নেই এবং অন্য কিছু দিয়ে নয়।

এখানে পোস্ট কিছু উদাহরণ পুনরায় ব্যবহার করতে।

কোডের এই অংশটি staticআরম্ভকারী ব্যবহার না করে পুনরায় লেখা যেতে পারে ।

পদ্ধতি # 1: সাথে static

private static final HashMap<String, String> MAP;
static {
    MAP.put("banana", "honey");
    MAP.put("peanut butter", "jelly");
    MAP.put("rice", "beans");
  }

পদ্ধতি # 2: ছাড়াই static

private static final HashMap<String, String> MAP = getMap();
private static HashMap<String, String> getMap()
{
    HashMap<String, String> ret = new HashMap<>();
    ret.put("banana", "honey");
    ret.put("peanut butter", "jelly");
    ret.put("rice", "beans");
    return ret;
}

10

এটির কিছু অস্তিত্ব থাকার প্রয়োজন রয়েছে:

  1. আরম্ভের static finalসদস্যদের যার আদ্যক্ষর হতে পারে ব্যতিক্রম throw
  2. static finalগণিত মান সহ সদস্যদের সূচনা

লোকেরা static {}ক্লাসটি রানটাইমের অভ্যন্তরে নির্ভর করে এমন জিনিসগুলিকে আরম্ভ করার জন্য একটি সুবিধাজনক উপায় হিসাবে ব্যবহার করে - যেমন নির্দিষ্ট শ্রেণীর বোঝা রয়েছে কিনা তা নিশ্চিতকরণ (যেমন, জেডিবিসি ড্রাইভার)। এটি অন্য উপায়ে করা যেতে পারে; যাইহোক, আমি উপরে উল্লিখিত দুটি জিনিস কেবলমাত্র static {}ব্লকের মতো একটি নির্মাণ দিয়েই করা যেতে পারে ।


8

স্ট্যাটিক ব্লকগুলিতে কোনও অবজেক্ট তৈরি হওয়ার আগে আপনি ক্লাসের জন্য একবার কোডের বিটগুলি কার্যকর করতে পারেন।

যেমন

class A {
  static int var1 = 6;
  static int var2 = 9;
  static int var3;
  static long var4;

  static Date date1;
  static Date date2;

  static {
    date1 = new Date();

    for(int cnt = 0; cnt < var2; cnt++){
      var3 += var1;
    }

    System.out.println("End first static init: " + new Date());
  }
}

7

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

public enum Language { 
  ENGLISH("eng", "en", "en_GB", "en_US"),   
  GERMAN("de", "ge"),   
  CROATIAN("hr", "cro"),   
  RUSSIAN("ru"),
  BELGIAN("be",";-)");

  static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>(); 
  static { 
    for (Language l:Language.values()) { 
      // ignoring the case by normalizing to uppercase
      ALIAS_MAP.put(l.name().toUpperCase(),l); 
      for (String alias:l.aliases) ALIAS_MAP.put(alias.toUpperCase(),l); 
    } 
  } 

  static public boolean has(String value) { 
    // ignoring the case by normalizing to uppercase
    return ALIAS_MAP.containsKey(value.toUpper()); 
  } 

  static public Language fromString(String value) { 
    if (value == null) throw new NullPointerException("alias null"); 
    Language l = ALIAS_MAP.get(value); 
    if (l == null) throw new IllegalArgumentException("Not an alias: "+value); 
    return l; 
  } 

  private List<String> aliases; 
  private Language(String... aliases) { 
    this.aliases = Arrays.asList(aliases); 
  } 
} 

এখানে ইনিশিয়ালাইজারটি মূল সূচিপত্র ALIAS_MAPটাইপটিতে ফিরে এলিয়াসের সেট ম্যাপ করতে একটি সূচক ( ) বজায় রাখতে ব্যবহৃত হয় । এটি Enumনিজের দ্বারা সরবরাহিত অন্তর্নির্মিত মানটি পদ্ধতিতে একটি এক্সটেনশন হিসাবে অভিযুক্ত ।

আপনি দেখতে পাচ্ছেন, স্থির আরম্ভকারী এমনকি privateক্ষেত্রটিও অ্যাক্সেস করে aliases। এটি বুঝতে গুরুত্বপূর্ণ যে staticব্লকের ইতিমধ্যে Enumমান উদাহরণগুলি অ্যাক্সেস রয়েছে (উদাঃ ENGLISH)। এটি কারণ হিসাবে আরম্ভের আদেশ কার্যকর করার ক্ষেত্রেEnum ধরনের , শুধু যেন static privateক্ষেত্র দৃষ্টান্ত সঙ্গে সক্রিয়া করা হয়েছে সামনে staticব্লক নামক করা হয়েছে:

  1. দ্য Enum স্থির ক্ষেত্রগুলি। এটির জন্য এনাম কনস্ট্রাক্টর এবং দৃষ্টান্তের ব্লকগুলির প্রয়োজন হয় এবং প্রথমে হ'ল ইনস্ট্যান্সের সূচনাও।
  2. static সংঘবদ্ধতার ক্রমে স্থির ক্ষেত্রগুলির ব্লক এবং সূচনা initial

এই আউট-অফ-অর্ডার ইনিশিয়ালেশন ( staticব্লকের আগে কনস্ট্রাক্টর ) নোট করা গুরুত্বপূর্ণ। এটি যখন ঘটে তখন আমরা স্থির ক্ষেত্রগুলিকে সিঙ্গলটনের অনুরূপ উদাহরণগুলি দিয়ে তৈরি করি (সরলীকরণ তৈরি করা হয়):

public class Foo {
  static { System.out.println("Static Block 1"); }
  public static final Foo FOO = new Foo();
  static { System.out.println("Static Block 2"); }
  public Foo() { System.out.println("Constructor"); }
  static public void main(String p[]) {
    System.out.println("In Main");
    new Foo();
  }
}

আমরা যা দেখি তা হ'ল নিম্নলিখিত আউটপুটটি:

Static Block 1
Constructor
Static Block 2
In Main
Constructor

পরিষ্কার যে স্থির সূচনা আসলে আগে হতে পারে কনস্ট্রাক্টরের এবং তার পরেও :

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

এ সম্পর্কিত আরও তথ্যের জন্য " কার্যকর জাভা " বইটি দেখুন ।


1
অ্যাক্সেস থাকার aliasesঅর্থ এই নয় যে স্ট্যাটিক ব্লক অ স্থির সদস্যদের অ্যাক্সেস করতে পারে। / স্ট্যাটিক / পদ্ধতি দ্বারা ফিরে aliasesআসা Languageমানগুলির মাধ্যমে অ্যাক্সেস করা হয় values()। যেমন আপনি উল্লেখ করেছেন যে এনাম ভেরিয়েবলগুলি ইতিমধ্যে সেই সময়ে পাওয়া যায় তা অস্বাভাবিক কিছু - নিয়মিত ক্লাসের অ স্থির সদস্যরা এই পরিস্থিতিতে অ্যাক্সেসযোগ্য হবে না।
ইগনাজিও

স্ট্যাটিক ব্লকটি এখনও কেবল স্থিতিশীল ক্ষেত্রগুলিতে অ্যাক্সেস করছে (আপনার এনাম ইংলিশ, জার্মানের ক্ষেত্রে, ...) যা এই ক্ষেত্রে অবজেক্ট। যেহেতু স্ট্যাটিক ক্ষেত্রগুলি সেগুলি নিজেরাই বস্তু, তাই আপনি স্থির বস্তুর উদাহরণ ক্ষেত্রটি অ্যাক্সেস করতে পারেন।
স্বামী পিআর

1
class Foo { static final Foo Inst1; static final Foo Inst2; static{ Inst1 = new Foo("Inst1"); Inst2 = new Foo("Inst2"); } static { System.out.println("Inst1: " + Inst1.member); System.out.println("Inst2: " + Inst2.member); } private final String member; private Foo(String member){ this.member = member; } } উপরের কোডটি এনাম উদাহরণ থেকে পৃথক নয় এবং এখনও স্থির ব্লকের অভ্যন্তরে উদাহরণের পরিবর্তনশীল অ্যাক্সেসের অনুমতি দেয়
স্বামী পিআর

@ স্বামীপিআরটি সত্যই এটি আমার বিস্ময়ের জন্য সংকলন করেছে এবং আমাকে সম্মত হতে হবে যে কোডটি নীতিগতভাবে আলাদা নয়। আমাকে জাভা স্পেসটি আবার পড়তে হবে, আমি অনুভব করছি যে আমি এখানে কিছু মিস করেছি। ভাল প্রতিক্রিয়া ফিরে, ধন্যবাদ।
YoYo

@ সোয়ামিআরপিআর ইস্যুটি সত্যিই আমাদের একটি ব্যবহার করা উচিত Enum। গ্যারান্টি দেওয়ার সর্বোত্তম উপায় হ'ল আমরা একক দৃষ্টান্তগুলিতে ইঙ্গিত করছি - এখানে দেখুন । এবং আপনার পয়েন্টগুলিতে, আমি বেশ কয়েকটি আপডেট করেছি।
YoYo

3

যদি আপনার স্ট্যাটিক ভেরিয়েবলগুলি রানটাইমে সেট করা প্রয়োজন তবে একটি static {...}ব্লক খুব সহায়ক।

উদাহরণস্বরূপ, আপনার যদি স্থিতিশীল সদস্যকে কোনও মানের মধ্যে সেট করতে হয় যা কোনও কনফিগার ফাইল বা ডাটাবেসে সংরক্ষণ করা হয়।

আপনি যখন স্থায়ী Mapসদস্যের সাথে মান যুক্ত করতে চান তখনও দরকারী যখন আপনি প্রাথমিক সদস্য ঘোষণায় এই মানগুলি যুক্ত করতে পারবেন না।


3

সুতরাং আপনার একটি স্থিতিশীল ক্ষেত্র রয়েছে (এটি "বর্গ ভেরিয়েবল" নামেও পরিচিত কারণ এটি শ্রেণীর অন্তর্গত নয় বরং শ্রেণীর অন্তর্গত; অন্য কথায় এটি কোনও বস্তুর পরিবর্তে শ্রেণীর সাথে সম্পর্কিত) এবং আপনি এটি শুরু করতে চান initial সুতরাং আপনি যদি এই শ্রেণীর কোনও উদাহরণ তৈরি করতে না চান এবং আপনি এই স্থিতিশীল ক্ষেত্রটি পরিচালনা করতে চান তবে আপনি তিনটি উপায়ে এটি করতে পারেন:

1- আপনি ভেরিয়েবলটি ঘোষণা করার সময় এটি শুরু করুন:

static int x = 3;

2- একটি স্ট্যাটিক ইনিশিয়ালাইজিং ব্লক রয়েছে:

static int x;

static {
 x=3;
}

3- একটি শ্রেণিবদ্ধ পদ্ধতি (স্ট্যাটিক পদ্ধতি) রয়েছে যা শ্রেণি ভেরিয়েবলটি অ্যাক্সেস করে এবং এটি সূচনা করে: এটি উপরের স্ট্যাটিক ব্লকের বিকল্প; আপনি একটি ব্যক্তিগত স্ট্যাটিক পদ্ধতি লিখতে পারেন:

public static int x=initializeX();

private static int initializeX(){
 return 3;
}

এখন আপনি স্থির পদ্ধতির পরিবর্তে স্ট্যাটিক ইনিশিয়ালাইজিং ব্লকটি ব্যবহার করবেন কেন?

আপনার প্রোগ্রামে আপনার যা প্রয়োজন তা নির্ভরযোগ্য। তবে আপনাকে জানতে হবে যে স্ট্যাটিক ইনিশিয়ালিং ব্লকটি একবার কল করা হয় এবং শ্রেণি পদ্ধতির একমাত্র সুবিধা হ'ল যদি আপনাকে শ্রেণীর ভেরিয়েবলটি পুনরায় নতুনকরণের প্রয়োজন হয় তবে সেগুলি পরে পুনরায় ব্যবহার করা যেতে পারে।

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

দ্রষ্টব্য: স্থির ব্লকগুলিকে কোডটিতে প্রদর্শিত হয় সে অনুযায়ী কল করা হয়।

উদাহরণ 1:

class A{
 public static int a =f();

// this is a static method
 private static int f(){
  return 3;
 }

// this is a static block
 static {
  a=5;
 }

 public static void main(String args[]) {
// As I mentioned, you do not need to create an instance of the class to use the class variable
  System.out.print(A.a); // this will print 5
 }

}

উদাহরণ 2:

class A{
 static {
  a=5;
 }
 public static int a =f();

 private static int f(){
  return 3;
 }

 public static void main(String args[]) {
  System.out.print(A.a); // this will print 3
 }

}

0

পরিপূরক হিসাবে, @ পয়েন্ট মত বলেছেন

"স্ট্যাটিক" বিভাগের কোডগুলি শ্রেণীর লোড সময়ে কার্যকর করা হবে, শ্রেণীর কোনও উদাহরণ নির্মাণের আগে (এবং কোনও স্থির পদ্ধতি অন্য কোথাও থেকে ডাকার আগে)।

এটি System.loadLibrary("I_am_native_library")স্ট্যাটিক ব্লকে যুক্ত করার কথা ।

static{
    System.loadLibrary("I_am_a_library");
}

এটি সম্পর্কিত গ্রন্থাগারে মেমরিতে লোড হওয়ার আগে কোনও নেটিভ পদ্ধতি কল করার নিশ্চয়তা দিবে না।

ওরাকল থেকে লোডলিবারি অনুসারে :

এই লাইব্রেরির নামের সাথে যদি এই পদ্ধতিটিকে একাধিকবার বলা হয়, তবে দ্বিতীয় এবং পরবর্তী কলগুলি উপেক্ষা করা হবে।

সুতরাং বেশ অপ্রত্যাশিতভাবে, সিস্টেম.লোডলিবারি লাগানো লাইব্রেরিটি বহুবার লোড হওয়া এড়ানোর জন্য ব্যবহৃত হয় না।


0

আপনাকে প্রথমে বুঝতে হবে যে আপনার অ্যাপ্লিকেশন ক্লাসগুলি java.class.Classরানটাইম চলাকালীন নিজেরাই অবজেক্টগুলিতে ইনস্ট্যান্ট করা আছে । এটি যখন আপনার স্থির ব্লকগুলি চালিত হয়। সুতরাং আপনি আসলে এটি করতে পারেন:

public class Main {

    private static int myInt;

    static {
        myInt = 1;
        System.out.println("myInt is 1");
    }

    //  needed only to run this class
    public static void main(String[] args) {
    }

}

এবং এটি কনসোল করার জন্য "myInt is 1" মুদ্রণ করবে। মনে রাখবেন যে আমি কোনও শ্রেণি ইনস্ট্যান্টেশন করি নি।


0
static int B,H;
static boolean flag = true;
static{
    Scanner scan = new Scanner(System.in);
    B = scan.nextInt();
    scan.nextLine();
    H = scan.nextInt();

    if(B < 0 || H < 0){
        flag = false;
        System.out.println("java.lang.Exception: Breadth and height must be positive");
    } 
}

-1

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

Eg:-class Solution{
         // static int x=10;
           static int x;
       static{
        try{
          x=System.out.println();
          }
         catch(Exception e){}
        }
       }

     class Solution1{
      public static void main(String a[]){
      System.out.println(Solution.x);
        }
        }

এখন আমার স্ট্যাটিক ইনট এক্সটি ডায়নামিকভাবে আরম্ভ করবে ..বিকোজ যখন সংকলক সলিউশন.এক্স এ যাবে তখন এটি সলিউশন ক্লাস এবং স্ট্যাটিক ব্লক লোড লোডের সময় ক্লাস লোড করার সময় লোড করবে .. সুতরাং আমরা স্থিতিশীল ডেটা সদস্যকে গতিশীলভাবে আরম্ভ করতে সক্ষম হতে পারি ..

}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.