جامد فیلڈز
جب ہم کلاس لیول کے متغیر کی نشاندہی کرتے ہیں، تو ہم اشارہ کرتے ہیں کہ قدر کا تعلق کلاس سے ہے۔ اگر آپ ایسا نہیں کرتے ہیں، تو متغیر کی قدر اس کلاس کا استعمال کرتے ہوئے تخلیق کردہ آبجیکٹ سے منسلک ہو جائے گی۔ اس کا کیا مطلب ہے؟ اور حقیقت یہ ہے کہ اگر متغیر جامد نہیں ہے، تو اس کلاس کے ہر نئے آبجیکٹ کے پاس اس متغیر کی اپنی قدر ہوگی، جسے تبدیل کرکے ہم اسے صرف ایک شے میں تبدیل کرتے ہیں: مثال کے طور پر، ہمارے پاس کار کلاس ہے جس میں ایک غیر جامد متغیر:public class Car {
int km;
}
پھر بنیادی طور پر:
Car orangeCar = new Car();
orangeCar.km = 100;
Car blueCar = new Car();
blueCar.km = 85;
System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
ہمیں جو آؤٹ پٹ ملتا ہے وہ ہے:
Orange car - 100
Blue car - 85
جیسا کہ آپ دیکھ سکتے ہیں، ہر شے کا اپنا متغیر ہوتا ہے، جس کی تبدیلی صرف اس چیز کے لیے ہوتی ہے۔ ٹھیک ہے، اگر ہمارے پاس ایک جامد متغیر ہے، تو یہ عالمی قدر سب کے لیے یکساں ہے: اب ہمارے پاس ایک جامد متغیر والی کار ہے:
public class Car {
static int km;
}
پھر مین میں وہی کوڈ کنسول کو آؤٹ پٹ کرے گا:
Orange car - 85
Blue car - 85
سب کے بعد، ہمارے پاس ہم سب کے لئے ایک متغیر ہے، اور ہر بار ہم اسے تبدیل کرتے ہیں. جامد متغیرات تک رسائی عام طور پر کسی آبجیکٹ کے حوالہ سے نہیں ہوتی ہے - orangeCar.km، بلکہ کلاس کے نام سے - Car.km
جامد بلاک
دو ابتدائی بلاکس ہیں - باقاعدہ اور جامد۔ بلاک کا مقصد اندرونی متغیرات کو شروع کرنا ہے۔ اگر بلاک نارمل ہے تو اس کے ساتھ آبجیکٹ کے اندرونی متغیرات شروع کیے جاتے ہیں، لیکن اگر یہ جامد ہے، تو جامد متغیرات (یعنی کلاس ویری ایبلز) ان کے لیے تفویض کیے جاتے ہیں۔ جامد ابتدائی بلاک والی کلاس کی مثال:public class Car {
static int km;
static {
km = 150;
}
}
جامد طریقہ
جامد طریقے باقاعدہ طریقوں سے مختلف ہوتے ہیں کہ وہ کسی شے کے بجائے کلاس کے پابند بھی ہوتے ہیں۔ جامد طریقہ کی ایک اہم خاصیت یہ ہے کہ یہ صرف جامد متغیرات/طریقوں تک رسائی حاصل کر سکتا ہے۔ مثال کے طور پر، آئیے ایک ایسی کلاس کو دیکھتے ہیں جو ایک قسم کا کاؤنٹر ہو گا جو طریقہ کالوں پر نظر رکھتا ہے:public class Counter {
static int count;
public static void invokeCounter() {
count++;
System.out.println("Current counter value - " + count);
}
}
آئیے اسے مین میں کہتے ہیں:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
اور ہم کنسول پر آؤٹ پٹ حاصل کرتے ہیں:
Текущее meaning счётчика - 1
Текущее meaning счётчика - 2
Текущее meaning счётчика - 3
جاوا میں جامد کلاس
صرف ایک اندرونی کلاس ہی ایک جامد کلاس ہو سکتی ہے۔ ایک بار پھر، یہ طبقہ بیرونی طبقے سے منسلک ہے، اور اگر بیرونی طبقے کو کسی اور طبقے سے وراثت میں ملا ہے، تو یہ وراثت میں نہیں ملے گا۔ مزید برآں، اس کلاس کو وراثت میں مل سکتا ہے، بالکل اسی طرح جیسے یہ کسی دوسرے طبقے سے وراثت میں مل سکتا ہے اور ایک انٹرفیس کو نافذ کر سکتا ہے۔ بنیادی طور پر، ایک جامد نیسٹڈ کلاس کسی دوسرے اندرونی طبقے سے مختلف نہیں ہے، سوائے اس کے کہ اس کے آبجیکٹ میں بیرونی طبقے کے آبجیکٹ کا حوالہ نہیں ہوتا ہے جس نے اسے بنایا تھا۔ تاہم، یہ ایک جامد کلاس کو باقاعدہ نان نیسٹڈ سے ملتا جلتا بناتا ہے، کیونکہ فرق صرف اتنا ہے کہ اسے کسی اور کلاس میں لپیٹ دیا جاتا ہے۔ کچھ معاملات میں، یہ ہمارے لیے ایک فائدہ ہے، کیونکہ اس سے ہمیں بیرونی طبقے کے نجی جامد متغیرات تک رسائی حاصل ہے۔ نیسٹڈ سٹیٹک کلاس کی مثال:public class Vehicle {
public static class Car {
public int km;
}
}
اس کلاس کی ایک مثال بنانا اور اندرونی متغیر کی قدر ترتیب دینا:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
جامد طریقوں/متغیرات/کلاس کو استعمال کرنے کے لیے، ہمیں اس کلاس کی کوئی چیز بنانے کی ضرورت نہیں ہے۔ یقینا، رسائی میں ترمیم کرنے والوں کو مدنظر رکھا جانا چاہئے۔ مثال کے طور پر، فیلڈز private
صرف اس کلاس کے اندر قابل رسائی ہیں جس میں ان کا اعلان کیا گیا ہے۔ فیلڈز protected
پیکیج ( پیکیج ) کے اندر موجود تمام کلاسوں کے ساتھ ساتھ پیکج سے باہر تمام وراثتی کلاسوں کے لیے دستیاب ہیں۔ مزید تفصیلات کے لیے، مضمون " پرائیویٹ بمقابلہ محفوظ بمقابلہ عوامی " دیکھیں ۔ increment()
فرض کریں کہ کلاس میں ایک جامد طریقہ ہے Counter
جس کا کام counter کو بڑھانا ہے count
۔ اس طریقہ کو کال کرنے کے لیے، آپ فارم کی درخواست استعمال کر سکتے ہیں Counter.increment()
۔ Counter
جامد فیلڈ یا طریقہ تک رسائی کے لیے کسی کلاس کو انسٹیٹیوٹ کرنے کی ضرورت نہیں ہے ۔ یہ جامد اور غیر جامد اشیاء (کلاس ممبران) کے درمیان بنیادی فرق ہے۔ میں آپ کو ایک بار پھر یاد دلاتا ہوں کہ جامد کلاس ممبران براہ راست کلاس سے تعلق رکھتے ہیں، اس کی مثال سے نہیں۔ یعنی جامد متغیر کی قدر count
قسم کی تمام اشیاء کے لیے یکساں ہوگی Counter
۔ بعد میں اس مضمون میں، ہم جاوا میں سٹیٹک موڈیفائر کے استعمال کے بنیادی پہلوؤں کے ساتھ ساتھ کچھ خصوصیات پر غور کریں گے جو آپ کو پروگرامنگ کے کلیدی تصورات کو سمجھنے میں مدد کریں گے۔
جاوا میں سٹیٹک موڈیفائر کے بارے میں ہر پروگرامر کو کیا معلوم ہونا چاہیے۔
اس سیکشن میں، ہم جامد طریقوں، فیلڈز اور کلاسز کے استعمال کی بنیادی باتوں کو دیکھیں گے۔ آئیے متغیرات سے شروع کرتے ہیں۔-
آپ جامد سیاق و سباق، جیسے کہ طریقہ یا بلاک کے اندر کسی کلاس کے غیر جامد اراکین تک رسائی حاصل نہیں کر سکتے۔ ذیل میں کوڈ کو مرتب کرنے کے نتیجے میں ایک غلطی ہوگی:
public class Counter{ private int count; public static void main(String args[]){ System.out.println(count); //compile time error }}
یہ جاوا پروگرامرز کی طرف سے کی جانے والی سب سے عام غلطیوں میں سے ایک ہے، خاص طور پر نئے آنے والے۔ چونکہ طریقہ
main
جامد ہے، لیکن متغیرcount
نہیں ہے، اس صورت میں طریقہ کےprintln
اندر کا طریقہmain
"Compile time error" پھینک دے گا۔ -
مقامی متغیرات کے برعکس، جامد فیلڈز اور طریقے جاوا میں تھریڈ سے محفوظ نہیں ہیں۔ عملی طور پر، یہ ملٹی تھریڈ پروگرامنگ کی سیکورٹی سے متعلق مسائل کی سب سے عام وجوہات میں سے ایک ہے۔ اس بات پر غور کرتے ہوئے کہ کلاس کی ہر مثال میں ایک جامد متغیر کی ایک ہی کاپی ہوتی ہے، ایسے متغیر کو کلاس کے ذریعے محفوظ کرنے کی ضرورت ہے۔ لہذا، جامد متغیرات کا استعمال کرتے وقت، یقینی بنائیں کہ وہ دوڑ کے حالات جیسے مسائل سے بچنے کے لیے مناسب طریقے سے مطابقت پذیر ہیں۔
-
Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый an object для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы How нельзя лучше подходят в качестве методов-фабрик (
factory
), и методов-утorт (utility
). Классjava.lang.Math
— замечательный пример, в котором почти все методы статичны, по этой же причине классы-утorты в Java финализированы (final
). -
Другим важным моментом является то, что вы НЕ можете переопределять (
Override
) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass
), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass
) instead of переопределения. Это явление известно How сокрытие методов (hiding methods
). Это означает, что при обращении к статическому методу, который объявлен How в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:class Vehicle{ public static void kmToMiles(int km){ System.out.println("Inside parent class/static method"); } } class Car extends Vehicle{ public static void kmToMiles(int km){ System.out.println("Inside child class/static method "); } } public class Demo{ public static void main(String args[]){ Vehicle v = new Car(); v.kmToMiles(10); }}
Вывод в консоль:
Внутри родительского класса/статического метода
Код наглядно демонстрирует: несмотря на то, что an object имеет тип
Car
, вызван статический метод из классаVehicle
, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло! -
Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны How «вложенные статические классы» (
nested static class
). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса —HashMap.Entry
, который предоставляет структуру данных внутриHashMap
. Стоит заметить, также How и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявor пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator
), например компаратор по возрасту (AgeComparator
) в классе сотрудники (Employee
). -
Модификатор static также может быть объявлен в статичном блоке, более известным How «Статический блок инициализации» (
Static initializer block
), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему. -
یہ جاننا مفید ہے کہ جامد طریقے کمپائل کے وقت پابند ہوتے ہیں، بائنڈنگ ورچوئل یا غیر جامد طریقوں کے برخلاف، جو حقیقی آبجیکٹ پر رن ٹائم پر پابند ہوتے ہیں۔ لہذا، جاوا میں جامد طریقوں کو اوور رائڈ نہیں کیا جا سکتا کیونکہ رن ٹائم پولیمورفزم ان پر لاگو نہیں ہوتا ہے۔ کسی طریقہ کو جامد قرار دیتے وقت اس پر غور کرنے کی ایک اہم حد ہے۔ یہ تب ہی سمجھ میں آتا ہے جب وراثت کی کلاسوں کے ذریعہ اس طرح کے طریقہ کو اوور رائڈ کرنے کا کوئی امکان یا ضرورت نہ ہو۔ فیکٹری کے طریقے اور افادیت کے طریقے سٹیٹک موڈیفائر کو استعمال کرنے کی اچھی مثالیں ہیں۔ جوشوا بلوچ نے اپنی کتاب Effective Java میں کنسٹرکٹر پر جامد فیکٹری طریقہ استعمال کرنے کے متعدد فوائد کا خاکہ پیش کیا ، جسے زبان کے ہر پروگرامر کے لیے پڑھنا ضروری ہے۔
-
جامد بلاک کی ایک اہم خاصیت ابتداء ہے۔ کلاس کے میموری میں لوڈ ہونے کے بعد جامد فیلڈز یا متغیرات شروع کیے جاتے ہیں۔ ابتدائی ترتیب اوپر سے نیچے تک اسی ترتیب میں ہے جیسا کہ جاوا کلاس سورس فائل میں بیان کیا گیا ہے۔ چونکہ جامد فیلڈز کو تھریڈ سیف انداز میں شروع کیا جاتا ہے، اس لیے اس پراپرٹی کو لاگو کرنے کے لیے بھی استعمال کیا جاتا ہے
Singleton
۔Enum
اگر آپ کسی نہ کسی وجہ سے، جیسی فہرست استعمال نہیں کرتے ہیںSingleton
، تو آپ کے لیے ایک اچھا متبادل ہے۔ لیکن اس معاملے میں، یہ ذہن میں رکھنا ضروری ہے کہ یہ "سست" ابتدا نہیں ہے۔ اس کا مطلب یہ ہے کہ کسی کے "پوچھنے" سے پہلے ہی جامد فیلڈ کو شروع کیا جائے گا۔ اگر آبجیکٹ وسائل سے بھرپور ہے یا شاذ و نادر ہی استعمال ہوتا ہے، تو اسے جامد بلاک میں شروع کرنا آپ کے حق میں کام نہیں کرے گا۔ -
سیریلائزیشن کے دوران، متغیر کی طرح
transient
، جامد فیلڈز کو سیریلائز نہیں کیا جاتا ہے۔ درحقیقت، اگر آپ کسی بھی ڈیٹا کو کسی جامد فیلڈ میں محفوظ کرتے ہیں، تو ڈیسیریلائزیشن کے بعد نئی آبجیکٹ میں اس کی بنیادی (پہلے سے طے شدہ) قدر ہوگی، مثال کے طور پر، اگر جامد فیلڈ قسم کا متغیر تھا، توint
ڈیسیریلائزیشن کے بعد اس کی قدر صفر ہوگی، اگر قسمfloat
0.0 ہے، اگر قسمObject
-null
۔ سچ میں، یہ جاوا انٹرویوز میں سیریلائزیشن کے حوالے سے اکثر پوچھے جانے والے سوالات میں سے ایک ہے۔ کسی چیز کے بارے میں سب سے اہم ڈیٹا کو جامد فیلڈ میں ذخیرہ نہ کریں! -
اور آخر میں، کے بارے میں بات کرتے ہیں
static import
. اس ترمیم کار میں معیاری آپریٹر کے ساتھ بہت کچھ مشترک ہےimport
، لیکن اس کے برعکس، یہ آپ کو کلاس کے ایک یا تمام جامد اراکین کو درآمد کرنے کی اجازت دیتا ہے۔ جامد طریقوں کو درآمد کرتے وقت، ان تک رسائی حاصل کی جاسکتی ہے جیسے کہ وہ ایک ہی کلاس میں بیان کیے گئے ہیں، اسی طرح جب فیلڈز درآمد کرتے ہیں، تو ہم کلاس کا نام بتائے بغیر ان تک رسائی حاصل کرسکتے ہیں۔ یہ فیچر جاوا ورژن 1.5 میں متعارف کرایا گیا تھا، اور جب اسے صحیح طریقے سے استعمال کیا جائے تو کوڈ کی پڑھنے کی اہلیت بہتر ہو جاتی ہے۔ یہ تعمیر اکثر JUnit ٹیسٹوں میں پائی جاتی ہے ، کیونکہ تقریباً تمام ٹیسٹ ڈویلپرزstatic import
اسسٹ کے طریقے استعمال کرتے ہیں، مثال کے طور پر،assertEquals()
اور ان کے اوورلوڈ ڈپلیکیٹس۔ اگر کچھ واضح نہیں ہے تو، اضافی معلومات کے لیے خوش آمدید ۔
GO TO FULL VERSION