একটি খুব আকর্ষণীয় সন্ধান। এটি বুঝতে আমাদের জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন ( জেএলএস) খনন করতে হবে ) ।
কারণটি হ'ল কেবল final
একটি অ্যাসাইনমেন্টের অনুমতি দেয় । ডিফল্ট মানটি অবশ্য কোনও অ্যাসাইনমেন্ট নয় । প্রকৃতপক্ষে, এই জাতীয় প্রতিটি পরিবর্তনশীল (বর্গ ভেরিয়েবল, উদাহরণ ভেরিয়েবল, অ্যারের উপাদান) অ্যাসাইনমেন্টের আগে থেকেই তার পূর্বনির্ধারিত মানকে নির্দেশ করে । প্রথম অ্যাসাইনমেন্ট পরে রেফারেন্স পরিবর্তন করে।
ক্লাস ভেরিয়েবল এবং ডিফল্ট মান
নিম্নলিখিত উদাহরণটি একবার দেখুন:
private static Object x;
public static void main(String[] args) {
System.out.println(x); // Prints 'null'
}
আমরা স্পষ্টভাবে কোনও মান নির্ধারণ করি নি x
, যদিও এটি নির্দেশ করে null
, এটির ডিফল্ট মান। এটি তুলনা করুন §4.12.5 :
ভেরিয়েবলের প্রাথমিক মান
প্রতিটি শ্রেণি ভেরিয়েবল , উদাহরণ পরিবর্তনশীল, বা অ্যারের উপাদান তৈরি করা হলে এটি একটি ডিফল্ট মান দিয়ে শুরু করা হয় ( §15.9 , §15.10.2 )
নোট করুন যে এটি কেবল আমাদের উদাহরণের মতো এই ধরণের ভেরিয়েবলগুলির জন্য ধারণ করে। এটি স্থানীয় ভেরিয়েবলের জন্য ধারণ করে না, নিম্নলিখিত উদাহরণটি দেখুন:
public static void main(String[] args) {
Object x;
System.out.println(x);
// Compile-time error:
// variable x might not have been initialized
}
একই জেএলএস অনুচ্ছেদ থেকে:
একটি স্থানীয় ভেরিয়েবল ( §14.4 , .114.14 ) ব্যবহারের আগে স্পষ্টভাবে একটি মান দিতে হবে, হয় কোনও আরম্ভের ( §14.4 ) বা অ্যাসাইনমেন্ট ( .215.26 ) দ্বারা, এমনভাবে যাতে নির্দিষ্ট কার্যনির্বাহী ( § the 16 (ডিফিনেট অ্যাসাইনমেন্ট) )।
চূড়ান্ত পরিবর্তনশীল
এখন আমরা §4.12.4final
থেকে এক নজরে দেখুন :
চূড়ান্ত চলক
একটি পরিবর্তনশীল ঘোষণা করা যেতে পারে চূড়ান্ত । একটি চূড়ান্ত ভেরিয়েবল কেবল একবার নির্ধারিত হতে পারে । এটি একটি সংকলন-সময় ত্রুটি হয় যদি কোনও চূড়ান্ত ভেরিয়েবলকে অ্যাসাইনমেন্টের আগে অবিলম্বে অবিলম্বে নিযুক্ত না করা হয় ( §16 (ডিফিনেট অ্যাসাইনমেন্ট) )।
ব্যাখ্যা
এখন আপনার উদাহরণে ফিরে আসছি, সামান্য পরিবর্তিত:
public static void main(String[] args) {
System.out.println("After: " + X);
}
private static final long X = assign();
private static long assign() {
// Access the value before first assignment
System.out.println("Before: " + X);
return X + 1;
}
এটি আউটপুট
Before: 0
After: 1
আমরা যা শিখেছি তা প্রত্যাহার করুন। পদ্ধতির ভিতরে assign
ভেরিয়েবল বরাদ্দX
করা হয়নি এখনো একটি মান। সুতরাং, এটি তার ডিফল্ট মানটির দিকে নির্দেশ করে যেহেতু এটি একটি শ্রেণি পরিবর্তনশীল এবং জেএলএস অনুসারে এই পরিবর্তনগুলি সর্বদা তাত্ক্ষণিকভাবে তাদের ডিফল্ট মানগুলিতে নির্দেশ করে (স্থানীয় ভেরিয়েবলের বিপরীতে)। assign
পদ্ধতির পরে X
চলকটির মান নির্ধারিত হয় 1
এবং এর কারণে final
আমরা এটিকে আর পরিবর্তন করতে পারি না। সুতরাং নিম্নলিখিত কারণে কাজ করে না final
:
private static long assign() {
// Assign X
X = 1;
// Second assign after method will crash
return X + 1;
}
জেএলএসে উদাহরণ
@ অ্যান্ড্রুকে ধন্যবাদ জানিয়ে আমি একটি জেএলএস অনুচ্ছেদ পেয়েছি যা ঠিক এই দৃশ্যের অন্তর্ভুক্ত করে, এটি এটি প্রদর্শিতও করে।
তবে প্রথমে একবার দেখে নেওয়া যাক
private static final long X = X + 1;
// Compile-time error:
// self-reference in initializer
কেন এই অনুমতি দেওয়া হচ্ছে না, যেখানে পদ্ধতি থেকে অ্যাক্সেস রয়েছে? Look8.3.3 এ একবার দেখুন যা ক্ষেত্রটিতে অ্যাক্সেস সীমাবদ্ধ থাকলে যদি ক্ষেত্রটি এখনও আরম্ভ না করা হয় talks
এটি শ্রেণি ভেরিয়েবলের জন্য প্রাসঙ্গিক কিছু বিধি তালিকাবদ্ধ করে:
f
শ্রেণি বা ইন্টারফেসে ঘোষিত শ্রেণীর ভেরিয়েবলের সাধারণ নাম দ্বারা একটি রেফারেন্সের জন্য C
, এটি a সংকলন-সময় ত্রুটি যদি :
রেফারেন্সটি একটি বর্গ পরিবর্তনীয় প্রারম্ভিক C
বা এর একটি স্ট্যাটিক আরম্ভকারীতে উপস্থিত হয়C
( §8.7 ) ; এবং
প্রারম্ভিক হয় আরম্ভকারীর মধ্যে প্রদর্শিত হয় f
নিজস্ব ডিক্লেয়ারের আরম্ভকারীতে বা ডিক্লেকারের বাম দিকে একটি বিন্দুতে উপস্থিত হয় f
; এবং
রেফারেন্স কোনও অ্যাসাইনমেন্ট এক্সপ্রেশনটির বাম দিকে নেই ( .215.26 ) ; এবং
অভ্যন্তরীণতম শ্রেণি বা ইন্টারফেসটি রেফারেন্সটি ঘিরে রয়েছে C
।
এটা সহজ, X = X + 1
নিয়মের দ্বারা ধরা পড়ে, পদ্ধতিটি অ্যাক্সেস পায় না। এমনকি তারা এই দৃশ্যের তালিকা তৈরি করে একটি উদাহরণ দেয়:
পদ্ধতি দ্বারা অ্যাক্সেসগুলি এইভাবে চেক করা হয় না, তাই:
class Z {
static int peek() { return j; }
static int i = peek();
static int j = 1;
}
class Test {
public static void main(String[] args) {
System.out.println(Z.i);
}
}
আউটপুট উত্পাদন করে:
0
কারণ জন্য সূচনাকারী পরিবর্তনশীল i
ব্যবহার অ্যাক্সেস করতে বর্গ পদ্ধতি উঁকি ভেরিয়েবলের মান j
সামনে j
তার পরিবর্তনশীল সূচনাকারী দ্বারা সক্রিয়া করা হয়েছে, যে সময়ে আপনার এটা এখনও তার ডিফল্ট মান আছে ( §4.12.5 )।
X
সদস্যকে রেফারেন্স দেওয়ার এই উপায়টি সুপার ক্লাস কনস্ট্রাক্টর শেষ হওয়ার আগে সাবক্লাস সদস্যকে উল্লেখ করার মতো, এটি আপনার সমস্যা এবং সংজ্ঞা নয়final
।