স্ট্যাটিক ভেরিয়েবল কখন শুরু হয়?


88

আমি ভাবছি যখন স্থিতিশীল ভেরিয়েবলগুলি তাদের ডিফল্ট মানগুলিতে আরম্ভ হয়। এটি কি সঠিক যে কোনও শ্রেণি লোড হয়ে গেলে, স্ট্যাটিক ওয়ারগুলি তৈরি করা হয় (বরাদ্দ), তারপরে ঘোষিত স্ট্যাটিক ইনিশিয়ালাইজার এবং প্রাথমিককরণ কার্যকর করা হয়? কোন বিন্দুতে ডিফল্ট মান দেওয়া হয়? এটি ফরোয়ার্ড রেফারেন্সের সমস্যার দিকে নিয়ে যায়।

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


4
আপনি যে উদ্ধৃতিটি উল্লেখ করছেন তা অন্তর্ভুক্ত করতে দয়া করে আপনার প্রশ্নটি সম্পাদনা করতে পারে।
অলিভার চার্লসওয়ার্থ

4
আপনি জাভা ভাষার স্পেসিফিকেশন পড়েছেন? এটি ইচ্ছাকৃতভাবে তাই খুব পঠনযোগ্য দলিল। আপনি যদি এটি পড়ে থাকেন তবে আপনি বুঝতে পারবেন কী চলছে। যদি তা না হয় তবে আপনি সর্বনিম্ন আরও একটি নির্দিষ্ট প্রশ্ন জিজ্ঞাসা করতে পারেন ...
মার্টেন বোদেউইস

আমি মনে করি এই প্রশ্নোত্তর একটি স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 3499214 এর এক ধাপ
স্টিফেন সি

উত্তর:


72

জাভা স্ট্যাটিক পরিবর্তনশীল পদ্ধতিগুলি থেকে দেখুন :

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

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

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

ক্ষেত্রে ভেতরের ক্লাস, তারা স্ট্যাটিক ক্ষেত্র থাকতে পারে না

একটি অভ্যন্তর শ্রেণি হল একটি নেস্টেড বর্গ যা স্পষ্টভাবে বা স্পষ্টভাবে ঘোষিত হয় না static

...

অভ্যন্তরীণ ক্লাসগুলি স্ট্যাটিক ইনিশিয়ালাইজার (§8.7) বা সদস্য ইন্টারফেস ঘোষণা করতে পারে না ...

অভ্যন্তরীণ ক্লাসগুলি স্থির সদস্যদের ঘোষণা করতে পারে না, যদি না তারা ধ্রুবক পরিবর্তনশীল হয় ...

জেএলএস 8.1.3 অভ্যন্তরীণ ক্লাস এবং সংযুক্তকরণ উদাহরণগুলি দেখুন

finalজাভাতে ক্ষেত্রগুলি তাদের ঘোষণার জায়গা থেকে আলাদাভাবে আরম্ভ করা যেতে পারে তবে এটি static finalক্ষেত্রগুলিতে প্রযোজ্য নয় । নীচে উদাহরণ দেখুন।

final class Demo
{
    private final int x;
    private static final int z;  //must be initialized here.

    static 
    {
        z = 10;  //It can be initialized here.
    }

    public Demo(int x)
    {
        this.x=x;  //This is possible.
        //z=15; compiler-error - can not assign a value to a final variable z
    }
}

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


4
In case of static inner classes, they can not have static fieldsটাইপোর মতো মনে হচ্ছে অভ্যন্তরীণ ক্লাসগুলি অ স্থিতিশীল।
ড্যানিয়েল লুবারভ

যদিও এর পরিবর্তে আপনার ব্যবহার করা উচিত
সুরজ জৈন

আপনি যখন কোনও জেভিএম ফায়ার করেন এবং প্রথমবারের জন্য কোনও ক্লাস লোড করেন (ক্লাসলোডার যখন ক্লাসটি কোনও উপায়ে প্রথমে রেফারেন্স করা হয় তখন এটি কোনও স্ট্যাটিক ব্লক বা ক্ষেত্রগুলি জেভিএমের মধ্যে 'লোড' হয়ে যায় এবং অ্যাক্সেসযোগ্য হয়।
nhoxbypass

4
দুর্ভাগ্যক্রমে এই জবাবটিতে স্ট্যাটিক্স কখন শুরু হয় সে সম্পর্কে কিছুটা সত্যই অসম্পূর্ণতা রয়েছে। দয়া করে স্ট্যাকওভারফ্লো . com/a/3499322/139985 দেখুন
স্টিফেন সি

15

দেখা:

বিশেষত সর্বশেষে বিশদ আরম্ভের ধাপগুলি সরবরাহ করে যা স্ট্যাটিক ভেরিয়েবলগুলি আরম্ভ করার সময় বানানটি নির্ধারণ করে এবং কোন ক্রমে (সতর্কতার সাথে যে finalক্লাস ভেরিয়েবল এবং ইন্টারফেস ক্ষেত্রগুলি সংকলন-সময় ধ্রুবকগুলি প্রথম শুরু করা হয়))

আমি নিশ্চিত নই যে পয়েন্ট 3 সম্পর্কে আপনার নির্দিষ্ট প্রশ্নটি কি (ধরে নিচ্ছেন নেস্টেড আপনি বোঝাচ্ছেন?) কী? বিস্তারিত সিকোয়েন্সে বলা হয়েছে এটি একটি পুনরাবৃত্তির সূচনা অনুরোধ হবে যাতে এটি আরম্ভ করা চালিয়ে যায়।


12

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


10

আরম্ভের ক্রমটি হ'ল:

  1. স্থির সূচনা ব্লক
  2. তাত্ক্ষণিক সূচনা ব্লক
  3. নির্মাতারা

প্রক্রিয়াটির বিশদটি জেভিএম স্পেসিফিকেশন ডকুমেন্টে ব্যাখ্যা করা হয়েছে ।


6

স্থির পরিবর্তনশীল

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

4

অন্যান্য প্রশ্ন থেকে কোড দিয়ে শুরু:

class MyClass {
  private static MyClass myClass = new MyClass();
  private static final Object obj = new Object();
  public MyClass() {
    System.out.println(obj); // will print null once
  }
}

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

এখন ক্লাসটি আরম্ভ করার পথে: objনতুন রিয়েল অবজেক্টের জন্য একটি রেফারেন্স তৈরি করা হয়, এবং আমরা শেষ করেছি।

যদি এটি একটি বিবৃতি দ্বারা সেট করা থাকে যেমন: MyClass mc = new MyClass();নতুন মাইক্লাস উদাহরণের জন্য স্থান আবার বরাদ্দ করা হয়েছে (এবং রেফারেন্সটি এতে স্থাপন করা হয়েছে mc)। কনস্ট্রাক্টর আবার এক্সিকিউটেড এবং আবার প্রিন্ট করে obj, যা এখন নাল নয়।

এখানে বাস্তব কৌতুক যে আপনি যখন ব্যবহার করেন new, হিসাবে WhatEverItIs weii = new WhatEverItIs( p1, p2 ); weiiঅবিলম্বে nulled মেমরির একটি বিট একটি রেফারেন্স দেওয়া হয়। জেভিএম তারপরে মানগুলি আরম্ভ করতে এবং কন্সট্রাক্টরটি চালাবে। তবে যদি আপনি এটির weii আগে কোনওভাবে রেফারেন্স করেন - অন্য থ্রেড থেকে এটি উল্লেখ করে বা শ্রেণীর সূচনা থেকে রেফারেন্স দিয়ে, উদাহরণস্বরূপ - আপনি নাল মানগুলিতে ভরা শ্রেণীর উদাহরণের দিকে তাকিয়ে আছেন।


4
প্রাথমিককরণ শেষ না হওয়া অবধি কোনও শ্রেণিকে প্রাথমিক হিসাবে চিহ্নিত করা হয়নি - অন্যথায় করা অর্থহীন হবে না। প্রাথমিক হিসাবে চিহ্নিত করা প্রায় শেষ পদক্ষেপ। জেএলএস 12.4.2 দেখুন ।
ডেভ নিউটন

@ ডেভিনিউটন: একবার কোনও কিছু ক্লাসের উল্লেখ করে এবং এটি শুরু করতে শুরু করলে, পরবর্তী সমস্ত উল্লেখ ক্লাসটিকে আরম্ভিত হিসাবে বিবেচনা করবে। তারা এটি আরম্ভ করার চেষ্টা করবে না এবং তারা এটি আরম্ভ করার জন্য অপেক্ষা করবে না। সুতরাং কোনও প্রোগ্রামের শুরু থেকে যে ক্ষেত্রগুলি শূন্য হয় না বলে মনে হয় তা প্রকৃতপক্ষে এক সময়ের জন্য শূন্য হতে পারে। এটি বুঝতে না পারার কারণেই সমস্ত বিভ্রান্তি ঘটছে। আমি মনে করি এটি নির্বিঘ্নিত শ্রেণিটিকে প্রথম রেফারেন্সের সূচনা হিসাবে "চিহ্নিত" করা খুব সহজ, অন্য সমস্ত রেফারেন্স এটিকে অন্তর্নিহিত হিসাবে বিবেচনা করে এবং এই কারণেই এটি ঘটে।
রাল্ফচাপিন

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

4

স্থিতিশীল ভেরিয়েবল নিম্নলিখিত তিনটি উপায়ে অন্তর্নিহিত হতে পারে অনুসরণ অনুসরণ হিসাবে আপনার পছন্দসই চয়ন করুন

  1. আপনি ঘোষণার সময় এটিকে নিবিষ্ট করতে পারেন
  2. অথবা আপনি স্ট্যাটিক ব্লক তৈরি করে করতে পারেন যেমন:

    static {
            // whatever code is needed for initialization goes here
        }
    
  3. স্ট্যাটিক ব্লকের বিকল্প রয়েছে - আপনি একটি ব্যক্তিগত স্ট্যাটিক পদ্ধতি লিখতে পারেন

    class name {
        public static varType myVar = initializeVar();
    
        private static varType initializeVar() {
            // initialization code goes here
        }
    }
    
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.