Execute method and create object with Reflection java
📖توضیحات درس
📄جزوه
مفاهیم کلیدی
-
Reflection یک قابلیت قدرتمند در Java که به برنامه اجازه میدهد در زمان اجرا (Runtime) ساختار درونی خود، شامل کلاسها، فیلدها، متدها و کانستراکتورها را بررسی کرده و حتی به اعضای
privateدسترسی پیدا کند. -
Method.invoke متدی در API رفلکشن که برای اجرای (Execute) یک
methodخاص بر روی یکobjectاستفاده میشود. این متد پارامترهایی برای مشخص کردن شیء هدف و آرگومانهای ورودی متد دریافت میکند. -
setAccessible متدی که برای تغییر وضعیت دسترسی اعضای کلاس (مانند
private fieldیاprivate method) به کار میرود. با مقداردهیtrueبه این متد، محدودیتهای دسترسی زبان جاوا دور زده شده و اجازه کار با اعضای مخفی کلاس داده میشود. -
Constructor.newInstance روشی برای ساخت یک
objectجدید از کلاس با استفاده از یکconstructorمشخص. این روش جایگزین مدرن و ایمنتر برایClass.newInstanceاست و اجازه میدهد حتی با کانستراکتورهای پارامتریک وprivateشیء بسازیم. -
getDeclaredMethods متدی که لیست تمامی متدهای تعریف شده در یک کلاس، اعم از
public،protectedوprivateرا برمیگرداند، برخلافgetMethodsکه فقط متدهای عمومی را شامل میشود. -
VarArgs (Variable Arguments) مکانیزمی در جاوا که اجازه میدهد یک متد تعداد نامشخصی آرگومان ورودی دریافت کند. در رفلکشن، متدهای
invokeوnewInstanceاز این قابلیت برای دریافت پارامترهای متد هدف استفاده میکنند.
موارد مصاحبه ای
-
چگونه میتوان یک متد private را با استفاده از Reflection فراخوانی کرد؟ ابتدا باید با استفاده از
getDeclaredMethodبه متد دسترسی پیدا کرد. سپس با فراخوانیsetAccessible(true)بر روی آن، سطح دسترسی را تغییر داد و در نهایت با استفاده ازinvokeآن را اجرا نمود. -
تفاوت بین getMethods و getDeclaredMethods در چیست؟ متد
getMethodsتمامی متدهایpublicکلاس و همچنین متدهای عمومی که از کلاسهای والد (مثلObject) به ارث رسیده را برمیگرداند. اماgetDeclaredMethodsفقط متدهایی را برمیگرداند که دقیقاً در همان کلاس تعریف شدهاند (شامل متدهای خصوصی)، اما متدهای ارثبری شده را شامل نمیشود. -
چرا استفاده از Class.newInstance() از جاوا ۹ به بعد منسوخ (Deprecated) شده است؟ زیرا این متد فقط میتواند کانستراکتورهای بدون آرگومان (no-arg) را فراخوانی کند و در مدیریت خطاهای زمان اجرا (Exceptions) دقت کافی ندارد. جایگزین بهتر، استفاده از
getConstructor().newInstance()است که انعطافپذیری و امنیت بیشتری دارد. -
آیا رفلکشن میتواند کپسولهسازی (Encapsulation) را نقض کند؟ بله، رفلکشن با استفاده از ابزارهایی مانند
setAccessible(true)میتواند به اعضایprivateکلاس دسترسی پیدا کرده و مقادیر آنها را تغییر دهد یا آنها را اجرا کند، که عملاً مرزهای کپسولهسازی را جابجا میکند.
سناریو کاربردی
در این ویدیو، سناریوی تغییر یک فیلد خصوصی و اجرای یک متد مخفی پیادهسازی شده است. فرض کنید کلاسی داریم که نام کاربر را در یک فیلد private نگه میدارد و تنها یک متد private برای تغییر آن دارد. در حالت عادی هیچ راهی برای فراخوانی این متد از خارج کلاس وجود ندارد.
مدرس نشان میدهد که چگونه با استفاده از رفلکشن، ابتدا متد changeFirstName را شناسایی کرده، قفل دسترسی آن را با setAccessible باز میکند و سپس با invoke نام جدید را به آن تزریق میکند. همچنین نشان داده میشود که چگونه میتوان با استفاده از یک private constructor که دو رشته دریافت میکند، یک نمونه کاملاً جدید از کلاس ایجاد کرد، در حالی که در کدنویسی معمولی این کار غیرممکن است.
بیشتر بدانید
-
نکته در مورد مدیریت خطا هنگام کار با رفلکشن، همیشه باید
Checked ExceptionsمانندNoSuchMethodExceptionیاIllegalAccessExceptionرا مدیریت کنید، زیرا رفلکشن در زمان اجرا عمل میکند و کامپایلر نمیتواند وجود یا عدم وجود متدها را پیشبینی کند. -
نکته در مورد شیء Class برای شروع هر عملیات رفلکشن، ابتدا باید به شیء
Classدسترسی داشته باشید که از دو راهobj.getClass()یاClassName.classامکانپذیر است. نسخه جدیدتر و مستقلتر نیز استفاده ازClass.forName("Full_Path_Address")است.
