
Cat
مثال کے طور پر، آپ ایک کلاس لکھ سکتے ہیں :
package learn.codegym;
public class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public void sayMeow() {
System.out.println("Meow!");
}
public void jump() {
System.out.println("Jump!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
آپ اس کے بارے میں سب کچھ جانتے ہیں، اور آپ اس میں موجود فیلڈز اور طریقے دیکھ سکتے ہیں۔ فرض کریں کہ آپ کو اچانک پروگرام میں جانوروں کی دوسری کلاسوں کو متعارف کرانے کی ضرورت ہے۔ Animal
آپ شاید سہولت کے لیے پیرنٹ کلاس کے ساتھ کلاس وراثت کا ڈھانچہ تشکیل دے سکتے ہیں ۔ اس سے پہلے، ہم نے ایک ویٹرنری کلینک کی نمائندگی کرنے والی ایک کلاس بھی بنائی تھی، جس میں ہم کسی Animal
چیز کو منتقل کر سکتے تھے (والدین کی کلاس کی مثال)، اور پروگرام نے جانور کے ساتھ مناسب سلوک اس بنیاد پر کیا کہ آیا وہ کتا تھا یا بلی۔ اگرچہ یہ سب سے آسان کام نہیں ہیں، پروگرام کمپائل کے وقت کلاسز کے بارے میں تمام ضروری معلومات سیکھنے کے قابل ہے۔ اس کے مطابق، جب آپ طریقہ کار Cat
میں ویٹرنری کلینک کلاس کے طریقوں پر کوئی اعتراض پاس کرتے main()
ہیں، تو پروگرام پہلے ہی جانتا ہے کہ یہ ایک بلی ہے، کتا نہیں۔ اب تصور کریں کہ ہمیں ایک مختلف کام کا سامنا ہے۔ ہمارا مقصد ایک کوڈ تجزیہ کار لکھنا ہے۔ ہمیں CodeAnalyzer
ایک طریقہ کے ساتھ ایک کلاس بنانے کی ضرورت ہے: void analyzeObject(Object o)
۔ یہ طریقہ ہونا چاہئے:
- اس کو پاس کردہ آبجیکٹ کی کلاس کا تعین کریں اور کنسول پر کلاس کا نام ڈسپلے کریں۔
- پاس شدہ کلاس کے تمام شعبوں کے ناموں کا تعین کریں، بشمول نجی، اور انہیں کنسول پر ڈسپلے کریں؛
- پاس شدہ کلاس کے تمام طریقوں کے ناموں کا تعین کریں، بشمول پرائیویٹ، اور انہیں کنسول پر ڈسپلے کریں۔
public class CodeAnalyzer {
public static void analyzeClass(Object o) {
// Print the name of the class of object o
// Print the names of all variables of this class
// Print the names of all methods of this class
}
}
اب ہم واضح طور پر دیکھ سکتے ہیں کہ یہ کام دوسرے کاموں سے کس طرح مختلف ہے جو آپ نے پہلے حل کیے ہیں۔ ہمارے موجودہ مقصد کے ساتھ، مشکل اس حقیقت میں ہے کہ نہ تو ہم اور نہ ہی پروگرام کو معلوم ہے کہ طریقہ analyzeClass()
کار میں کیا منتقل کیا جائے گا۔ اگر آپ ایسا پروگرام لکھتے ہیں، تو دوسرے پروگرامرز اسے استعمال کرنا شروع کر دیں گے، اور وہ اس طریقہ کار میں کچھ بھی پاس کر سکتے ہیں — کوئی معیاری جاوا کلاس یا کوئی دوسری کلاس جو وہ لکھتے ہیں۔ پاس شدہ کلاس میں متعدد متغیرات اور طریقے ہوسکتے ہیں۔ دوسرے لفظوں میں، ہمیں (اور ہمارے پروگرام) کو اندازہ نہیں ہے کہ ہم کن کلاسوں کے ساتھ کام کریں گے۔ لیکن پھر بھی، ہمیں اس کام کو مکمل کرنے کی ضرورت ہے۔ اور یہ وہ جگہ ہے جہاں معیاری Java Reflection API ہماری مدد کے لیے آتا ہے۔ Reflection API زبان کا ایک طاقتور ٹول ہے۔ اوریکل کی آفیشل دستاویزات تجویز کرتی ہیں کہ یہ طریقہ کار صرف تجربہ کار پروگرامرز کو استعمال کرنا چاہیے جو جانتے ہیں کہ وہ کیا کر رہے ہیں۔ آپ جلد ہی سمجھ جائیں گے کہ ہم اس طرح کی وارننگ پہلے سے کیوں دے رہے ہیں :) یہاں ان چیزوں کی فہرست ہے جو آپ Reflection API کے ساتھ کر سکتے ہیں:
- کسی چیز کی کلاس کی شناخت/تعین کریں۔
- کلاس موڈیفائرز، فیلڈز، طریقے، مستقل، کنسٹرکٹرز اور سپر کلاسز کے بارے میں معلومات حاصل کریں۔
- معلوم کریں کہ کون سے طریقے لاگو کردہ انٹرفیس سے تعلق رکھتے ہیں۔
- ایک ایسی کلاس کی مثال بنائیں جس کی کلاس کا نام اس وقت تک معلوم نہ ہو جب تک کہ پروگرام پر عمل نہ ہو۔
- حاصل کریں اور نام سے ایک مثال کے میدان کی قیمت مقرر کریں.
- ایک مثال کے طریقے کو نام سے کال کریں۔
کسی چیز کی کلاس کی شناخت / تعین کیسے کریں۔
آئیے بنیادی باتوں سے شروع کریں۔ جاوا ریفلیکشن انجن میں داخلے کا نقطہClass
کلاس ہے۔ جی ہاں، یہ واقعی مضحکہ خیز لگ رہا ہے، لیکن یہ وہی ہے جو عکاسی ہے :) Class
کلاس کا استعمال کرتے ہوئے، ہم سب سے پہلے ہمارے طریقہ کار میں پاس کردہ کسی بھی چیز کی کلاس کا تعین کرتے ہیں. آئیے ایسا کرنے کی کوشش کریں:
import learn.codegym.Cat;
public class CodeAnalyzer {
public static void analyzeClass(Object o) {
Class clazz = o.getClass();
System.out.println(clazz);
}
public static void main(String[] args) {
analyzeClass(new Cat("Fluffy", 6));
}
}
کنسول آؤٹ پٹ:
class learn.codegym.Cat
دو باتوں پر توجہ دیں۔ سب سے پہلے، ہم نے جان بوجھ کر Cat
کلاس کو الگ learn.codegym
پیکج میں ڈالا۔ اب آپ دیکھ سکتے ہیں کہ getClass()
طریقہ کلاس کا پورا نام لوٹاتا ہے۔ دوسرا، ہم نے اپنے متغیر کا نام دیا clazz
۔ یہ تھوڑا سا عجیب لگتا ہے۔ اسے "کلاس" کہنا معنی خیز ہوگا، لیکن جاوا میں "کلاس" ایک محفوظ لفظ ہے۔ مرتب کرنے والا متغیرات کو یہ کہنے کی اجازت نہیں دے گا۔ ہمیں کسی نہ کسی طرح اس کے ارد گرد حاصل کرنا پڑا :) ایک آغاز کے لئے برا نہیں! ہمارے پاس صلاحیتوں کی اس فہرست میں اور کیا تھا؟
کلاس موڈیفائرز، فیلڈز، طریقے، مستقل، کنسٹرکٹرز اور سپر کلاسز کے بارے میں معلومات کیسے حاصل کی جائیں۔
اب چیزیں مزید دلچسپ ہو رہی ہیں! موجودہ کلاس میں، ہمارے پاس کوئی مستقل یا پیرنٹ کلاس نہیں ہے۔ آئیے ایک مکمل تصویر بنانے کے لیے انہیں شامل کریں۔ سب سے آسان پیرنٹ کلاس بنائیںAnimal
:
package learn.codegym;
public class Animal {
private String name;
private int age;
}
اور ہم اپنی Cat
کلاس کو وارث بنائیں گے Animal
اور ایک مستقل شامل کریں گے:
package learn.codegym;
public class Cat extends Animal {
private static final String ANIMAL_FAMILY = "Feline family";
private String name;
private int age;
// ...the rest of the class
}
اب ہمارے پاس مکمل تصویر ہے! آئیے دیکھتے ہیں کہ عکاسی کرنے کے قابل ہے :)
import learn.codegym.Cat;
import java.util.Arrays;
public class CodeAnalyzer {
public static void analyzeClass(Object o) {
Class clazz = o.getClass();
System.out.println("Class name: " + clazz);
System.out.println("Class fields: " + Arrays.toString(clazz.getDeclaredFields()));
System.out.println("Parent class: " + clazz.getSuperclass());
System.out.println("Class methods: " + Arrays.toString(clazz.getDeclaredMethods()));
System.out.println("Class constructors: " + Arrays.toString(clazz.getConstructors()));
}
public static void main(String[] args) {
analyzeClass(new Cat("Fluffy", 6));
}
}
یہ ہے جو ہم کنسول پر دیکھتے ہیں:
Class name: class learn.codegym.Cat
Class fields: [private static final java.lang.String learn.codegym.Cat.ANIMAL_FAMILY, private java.lang.String learn.codegym.Cat.name, private int learn.codegym.Cat.age]
Parent class: class learn.codegym.Animal
Class methods: [public java.lang.String learn.codegym.Cat.getName(), public void learn.codegym.Cat.setName(java.lang.String), public void learn.codegym.Cat.sayMeow(), public void learn.codegym.Cat.setAge(int), public void learn.codegym.Cat.jump(), public int learn.codegym.Cat.getAge()]
Class constructors: [public learn.codegym.Cat(java.lang.String, int)]
ان تمام تفصیلی کلاس معلومات کو دیکھیں جو ہم حاصل کرنے کے قابل تھے! اور نہ صرف عوامی معلومات، بلکہ نجی معلومات بھی! نوٹ: private
متغیرات بھی فہرست میں دکھائے جاتے ہیں۔ کلاس کے ہمارے "تجزیہ" کو بنیادی طور پر مکمل سمجھا جا سکتا ہے: ہم analyzeObject()
ہر وہ چیز سیکھنے کے لیے طریقہ استعمال کر رہے ہیں جو ہم کر سکتے ہیں۔ لیکن یہ سب کچھ نہیں ہے جو ہم عکاسی کے ساتھ کر سکتے ہیں۔ ہم صرف سادہ مشاہدے تک محدود نہیں ہیں — ہم کارروائی کرنے کے لیے آگے بڑھیں گے! :)
اس کلاس کی مثال کیسے بنائی جائے جس کی کلاس کا نام اس وقت تک معلوم نہ ہو جب تک کہ پروگرام پر عمل نہ ہو۔
آئیے پہلے سے طے شدہ کنسٹرکٹر کے ساتھ شروع کریں۔ ہماریCat
کلاس میں ابھی تک ایک نہیں ہے، تو آئیے اسے شامل کریں:
public Cat() {
}
Cat
عکاسی ( createCat()
طریقہ) کا استعمال کرتے ہوئے آبجیکٹ بنانے کا کوڈ یہ ہے :
import learn.codegym.Cat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static Cat createCat() throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String className = reader.readLine();
Class clazz = Class.forName(className);
Cat cat = (Cat) clazz.newInstance();
return cat;
}
public static Object createObject() throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String className = reader.readLine();
Class clazz = Class.forName(className);
Object result = clazz.newInstance();
return result;
}
public static void main(String[] args) throws IOException, IllegalAccessException, ClassNotFoundException, InstantiationException {
System.out.println(createCat());
}
}
کنسول ان پٹ:
learn.codegym.Cat
کنسول آؤٹ پٹ:
Cat{name='null', age=0}
یہ کوئی غلطی نہیں ہے: کی قدریں name
اور age
کنسول پر ظاہر ہوتی ہیں کیونکہ ہم نے کلاس toString()
کے طریقہ کار میں ان کو آؤٹ پٹ کرنے کے لیے کوڈ لکھا تھا۔ Cat
یہاں ہم ایک کلاس کا نام پڑھتے ہیں جس کا آبجیکٹ ہم کنسول سے بنائیں گے۔ پروگرام اس کلاس کے نام کو پہچانتا ہے جس کا آبجیکٹ بنایا جانا ہے۔ 
newInstance()
ہوئے ، ہم اس کلاس کا ایک نیا آبجیکٹ بناتے ہیں۔ یہ اور بات ہے کہ Cat
کنسٹرکٹر دلائل کو بطور ان پٹ لیتا ہے۔ آئیے کلاس کے ڈیفالٹ کنسٹرکٹر کو ہٹا دیں اور اپنے کوڈ کو دوبارہ چلانے کی کوشش کریں۔
null
java.lang.InstantiationException: learn.codegym.Cat
at java.lang.Class.newInstance(Class.java:427)
کچھ غلط ہو گیا! ہمیں ایک خرابی ہوئی کیونکہ ہم نے ڈیفالٹ کنسٹرکٹر کا استعمال کرتے ہوئے ایک آبجیکٹ بنانے کے لیے ایک طریقہ کا مطالبہ کیا۔ لیکن اب ہمارے پاس ایسا کنسٹرکٹر نہیں ہے۔ لہذا جب newInstance()
طریقہ چلتا ہے، عکاسی کا طریقہ کار ہمارے پرانے کنسٹرکٹر کو دو پیرامیٹرز کے ساتھ استعمال کرتا ہے:
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
لیکن ہم نے پیرامیٹرز کے ساتھ کچھ نہیں کیا، گویا ہم ان کے بارے میں بالکل بھول گئے ہیں! کنسٹرکٹر کو دلائل دینے کے لئے عکاسی کا استعمال کرتے ہوئے تھوڑی سی "تخلیقی صلاحیت" کی ضرورت ہوتی ہے۔
import learn.codegym.Cat;
import java.lang.reflect.InvocationTargetException;
public class Main {
public static Cat createCat() {
Class clazz = null;
Cat cat = null;
try {
clazz = Class.forName("learn.codegym.Cat");
Class[] catClassParams = {String.class, int.class};
cat = (Cat) clazz.getConstructor(catClassParams).newInstance("Fluffy", 6);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return cat;
}
public static void main(String[] args) {
System.out.println(createCat());
}
}
کنسول آؤٹ پٹ:
Cat{name='Fluffy', age=6}
آئیے اپنے پروگرام میں کیا ہو رہا ہے اس پر گہری نظر ڈالیں۔ Class
ہم نے اشیاء کی ایک صف بنائی ۔
Class[] catClassParams = {String.class, int.class};
وہ ہمارے کنسٹرکٹر کے پیرامیٹرز کے مطابق ہیں (جس میں صرف String
اور int
پیرامیٹرز ہیں)۔ ہم انہیں clazz.getConstructor()
طریقہ پر منتقل کرتے ہیں اور مطلوبہ کنسٹرکٹر تک رسائی حاصل کرتے ہیں۔ newInstance()
اس کے بعد، ہمیں صرف ضروری دلائل کے ساتھ طریقہ کار کو کال کرنے کی ضرورت ہے ، اور واضح طور پر اعتراض کو مطلوبہ قسم پر ڈالنا نہ بھولیں: Cat
۔
cat = (Cat) clazz.getConstructor(catClassParams).newInstance("Fluffy", 6);
اب ہمارا اعتراض کامیابی سے تیار ہو گیا ہے! کنسول آؤٹ پٹ:
Cat{name='Fluffy', age=6}
ساتھ ساتھ آگے بڑھ رہے ہیں :)
نام کے ذریعہ مثال کے فیلڈ کی قیمت کیسے حاصل اور سیٹ کریں۔
تصور کریں کہ آپ کسی دوسرے پروگرامر کی لکھی ہوئی کلاس استعمال کر رہے ہیں۔ مزید برآں، آپ کے پاس اس میں ترمیم کرنے کی اہلیت نہیں ہے۔ مثال کے طور پر، ایک ریڈی میڈ کلاس لائبریری JAR میں پیک کی گئی ہے۔ آپ کلاسز کا کوڈ پڑھ سکتے ہیں، لیکن آپ اسے تبدیل نہیں کر سکتے۔ فرض کریں کہ پروگرامر جس نے اس لائبریری میں ایک کلاس بنائی (یہ ہماری پرانیCat
کلاس ہے)، ڈیزائن کو حتمی شکل دینے سے پہلے رات کو کافی نیند لینے میں ناکام رہا، اس نے فیلڈ کے لیے گیٹر اور سیٹٹر کو ہٹا دیا age
۔ اب یہ کلاس آپ کے پاس آئی ہے۔ یہ آپ کی تمام ضروریات کو پورا کرتا ہے، کیونکہ آپ کو Cat
اپنے پروگرام میں صرف اشیاء کی ضرورت ہے۔ لیکن آپ کو ان کے پاس ایک age
فیلڈ کی ضرورت ہے! یہ ایک مسئلہ ہے: ہم فیلڈ تک نہیں پہنچ سکتے، کیونکہ اس میں ترمیم private
کرنے والا ہے، اور گیٹر اور سیٹٹر کو نیند سے محروم ڈیولپر نے حذف کر دیا تھا جس نے کلاس بنائی تھی:/ ٹھیک ہے، عکاسی اس صورتحال میں ہماری مدد کر سکتی ہے! ہمارے پاس کلاس کے کوڈ تک رسائی ہے Cat
، لہذا ہم کم از کم یہ جان سکتے ہیں کہ اس میں کون سے فیلڈز ہیں اور انہیں کیا کہا جاتا ہے۔ اس معلومات سے لیس، ہم اپنا مسئلہ حل کر سکتے ہیں:
import learn.codegym.Cat;
import java.lang.reflect.Field;
public class Main {
public static Cat createCat() {
Class clazz = null;
Cat cat = null;
try {
clazz = Class.forName("learn.codegym.Cat");
cat = (Cat) clazz.newInstance();
// We got lucky with the name field, since it has a setter
cat.setName("Fluffy");
Field age = clazz.getDeclaredField("age");
age.setAccessible(true);
age.set(cat, 6);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return cat;
}
public static void main(String[] args) {
System.out.println(createCat());
}
}
جیسا کہ تبصرے میں کہا گیا ہے، name
فیلڈ کے ساتھ ہر چیز سیدھی ہے، کیونکہ کلاس ڈویلپرز نے ایک سیٹر فراہم کیا ہے۔ آپ پہلے سے ہی جانتے ہیں کہ ڈیفالٹ کنسٹرکٹرز سے اشیاء کیسے بنائیں: ہمارے پاس newInstance()
اس کے لیے ہے۔ لیکن ہمیں دوسرے فیلڈ کے ساتھ کچھ ٹنکرنگ کرنا پڑے گا۔ آئیے معلوم کریں کہ یہاں کیا ہو رہا ہے :)
Field age = clazz.getDeclaredField("age");
یہاں، اپنے Class clazz
آبجیکٹ کا استعمال کرتے ہوئے، ہم طریقہ age
کے ذریعے فیلڈ تک رسائی حاصل کرتے ہیں۔ getDeclaredField()
یہ ہمیں عمر کے میدان کو بطور Field age
آبجیکٹ حاصل کرنے دیتا ہے۔ لیکن یہ کافی نہیں ہے، کیونکہ ہم صرف private
فیلڈز کو قدریں تفویض نہیں کر سکتے۔ ایسا کرنے کے لیے، ہمیں طریقہ استعمال کرکے فیلڈ کو قابل رسائی بنانا ہوگا setAccessible()
:
age.setAccessible(true);
ایک بار جب ہم اسے کسی فیلڈ میں کرتے ہیں، تو ہم ایک قدر تفویض کر سکتے ہیں:
age.set(cat, 6);
جیسا کہ آپ دیکھ سکتے ہیں، ہمارے Field age
آبجیکٹ میں ایک قسم کا انسائیڈ آؤٹ سیٹر ہوتا ہے جس سے ہم ایک int ویلیو پاس کرتے ہیں اور وہ آبجیکٹ جس کی فیلڈ کو تفویض کیا جانا ہے۔ ہم اپنا main()
طریقہ چلاتے ہیں اور دیکھتے ہیں:
Cat{name='Fluffy', age=6}
بہترین! ہم نے کر لیا! :) دیکھتے ہیں ہم اور کیا کر سکتے ہیں...
کسی مثال کے طریقہ کو نام سے کیسے پکارا جائے۔
آئیے پچھلی مثال میں صورتحال کو قدرے تبدیل کرتے ہیں۔ ہم کہتے ہیں کہCat
کلاس ڈویلپر نے گیٹرز اور سیٹرز کے ساتھ کوئی غلطی نہیں کی۔ اس سلسلے میں سب کچھ ٹھیک ہے۔ اب مسئلہ مختلف ہے: ایک طریقہ ہے جس کی ہمیں ضرور ضرورت ہے، لیکن ڈویلپر نے اسے نجی بنا دیا:
private void sayMeow() {
System.out.println("Meow!");
}
اس کا مطلب ہے کہ اگر ہم اپنے پروگرام میں آبجیکٹ بناتے ہیں ، تو ہم ان پر میتھڈ کو Cat
کال نہیں کر پائیں گے ۔ sayMeow()
ہمارے پاس بلیاں ہوں گی جو میانو نہیں کرتی ہیں؟ یہ عجیب ہے :/ ہم اسے کیسے ٹھیک کریں گے؟ ایک بار پھر، Reflection API ہماری مدد کرتا ہے! ہمیں اس طریقہ کا نام معلوم ہے جس کی ہمیں ضرورت ہے۔ باقی سب کچھ تکنیکی ہے:
import learn.codegym.Cat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void invokeSayMeowMethod() {
Class clazz = null;
Cat cat = null;
try {
cat = new Cat("Fluffy", 6);
clazz = Class.forName(Cat.class.getName());
Method sayMeow = clazz.getDeclaredMethod("sayMeow");
sayMeow.setAccessible(true);
sayMeow.invoke(cat);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
invokeSayMeowMethod();
}
}
یہاں ہم وہی کچھ کرتے ہیں جو ہم نے نجی فیلڈ تک رسائی کے وقت کیا تھا۔ سب سے پہلے، ہمیں وہ طریقہ ملتا ہے جس کی ہمیں ضرورت ہے۔ یہ ایک Method
آبجیکٹ میں شامل ہے:
Method sayMeow = clazz.getDeclaredMethod("sayMeow");
طریقہ getDeclaredMethod()
ہمیں نجی طریقوں تک پہنچنے دیتا ہے۔ اگلا، ہم طریقہ کار کو قابل کال بناتے ہیں:
sayMeow.setAccessible(true);
اور آخر میں، ہم مطلوبہ اعتراض پر طریقہ کو کال کرتے ہیں:
sayMeow.invoke(cat);
یہاں، ہماری میتھڈ کال ایک "کال بیک" کی طرح نظر آتی ہے: ہم کسی چیز کو مطلوبہ طریقہ ( cat.sayMeow()
) کی طرف اشارہ کرنے کے لیے مدت استعمال کرنے کے عادی ہیں، لیکن جب عکاسی کے ساتھ کام کرتے ہیں، تو ہم اس طریقے سے گزر جاتے ہیں جس پر ہم کال کرنا چاہتے ہیں۔ وہ طریقہ. ہمارے کنسول پر کیا ہے؟
Meow!
سب کچھ کام کیا! :) اب آپ ان وسیع امکانات کو دیکھ سکتے ہیں جو جاوا کا ریفلیکشن میکانزم ہمیں دیتا ہے۔ مشکل اور غیر متوقع حالات میں (جیسے بند لائبریری سے کلاس کے ساتھ ہماری مثالیں)، یہ واقعی ہماری بہت مدد کر سکتی ہے۔ لیکن، کسی بھی عظیم طاقت کی طرح، یہ بڑی ذمہ داری لاتا ہے۔ عکاسی کے نقصانات کو اوریکل ویب سائٹ پر ایک خاص حصے میں بیان کیا گیا ہے۔
تین اہم نقصانات ہیں:
-
کارکردگی بدتر ہے۔ عکاسی کا استعمال کرتے ہوئے کہلائے جانے والے طریقوں کی کارکردگی عام طریقے سے کہے جانے والے طریقوں سے بدتر ہوتی ہے۔
-
حفاظتی پابندیاں ہیں۔ عکاسی کا طریقہ کار ہمیں رن ٹائم کے وقت پروگرام کے رویے کو تبدیل کرنے دیتا ہے۔ لیکن آپ کے کام کی جگہ پر، ایک حقیقی پروجیکٹ پر کام کرتے وقت، آپ کو ایسی حدود کا سامنا کرنا پڑ سکتا ہے جو اس کی اجازت نہیں دیتی ہیں۔
-
اندرونی معلومات کی نمائش کا خطرہ۔ یہ سمجھنا ضروری ہے کہ عکاسی انکیپسولیشن کے اصول کی براہ راست خلاف ورزی ہے: یہ ہمیں نجی شعبوں، طریقوں وغیرہ تک رسائی کی اجازت دیتا ہے۔ مجھے نہیں لگتا کہ مجھے یہ بتانے کی ضرورت ہے کہ OOP کے اصولوں کی براہ راست اور واضح خلاف ورزی کا سہارا لیا جانا چاہئے۔ صرف انتہائی انتہائی صورتوں میں، جب آپ کے قابو سے باہر وجوہات کی بنا پر کسی مسئلے کو حل کرنے کے کوئی اور طریقے نہ ہوں۔
GO TO FULL VERSION