Access/Modify Fields with Reflection
📖توضیحات درس
📄جزوه
مفاهیم کلیدی
-
Reflection مکانیزمی در جاوا که به برنامهنویس اجازه میدهد در زمان اجرا (Runtime) به ساختار داخلی کلاسها، متدها و فیلدها دسترسی داشته باشد، آنها را بررسی کند (Inspect) و حتی مقادیر آنها را تغییر دهد (Modify).
-
Field شیئی در پکیج Reflection که نماینده یک متغیر (Variable) در کلاس است. از طریق این شیء میتوان به متادیتاها، نوع داده و مقدار متغیر دسترسی پیدا کرد.
-
getFieldمتدی که فقط برای دسترسی به فیلدهایpublicیک کلاس استفاده میشود. اگر فیلد مورد نظرprivateباشد، این متد آن را پیدا نمیکند. -
getDeclaredFieldمتدی که به شما اجازه میدهد به تمامی فیلدهای تعریف شده در یک کلاس، از جمله فیلدهایprivateوprotectedدسترسی داشته باشید. -
setAccessibleمتدی که برای دور زدن محدودیتهای دسترسی جاوا به کار میرود. با مقداردهیtrueبه این متد، میتوان به فیلدهایprivateدسترسی پیدا کرد یا مقدار فیلدهایfinalرا تغییر داد. -
Static Field فیلدی که متعلق به خود کلاس است و نه یک Instance خاص. در Reflection برای کار با این فیلدها، نیازی به پاس دادن یک آبجکت مشخص نیست و میتوان از مقدار
nullاستفاده کرد.
موارد مصاحبه ای
-
چگونه میتوان به یک فیلد
privateکه هیچ متد Getter یا Setter ندارد دسترسی پیدا کرد؟ با استفاده از متدgetDeclaredFieldبرای دریافت فیلد و سپس فراخوانیsetAccessible(true)روی آن شیء فیلد، میتوان سد امنیتی جاوا را شکست و به مقدار آن دسترسی پیدا کرد یا آن را تغییر داد. -
تفاوت اصلی
getFieldوgetDeclaredFieldدر چیست؟ متدgetFieldفقط فیلدهایpublicرا برمیگرداند (شامل فیلدهای ارثبری شده)، در حالی کهgetDeclaredFieldتمامی فیلدهایی که مستقیماً در خود کلاس تعریف شدهاند (اعم از private، public و غیره) را شامل میشود اما فیلدهای ارثبری شده را نمایش نمیدهد. -
آیا رفلکشن میتواند مقدار یک فیلد
finalرا تغییر دهد؟ بله، با استفاده از رفلکشن و متدsetAccessible(true)میتوان حتی مقدار فیلدهایی کهfinalتعریف شدهاند را پس از مقداردهی اولیه تغییر داد. البته این کار به دلیل شکستن اصول طراحی کلاس، باید با احتیاط فراوان انجام شود. -
هنگام خواندن یا نوشتن مقدار یک فیلد
staticدر رفلکشن، چه آبجکتی باید به متدgetیاsetپاس داده شود؟ از آنجایی که فیلدهایstaticمتعلق به کلاس هستند و به هیچ آبجکت یا Instance خاصی وابستگی ندارند، میتوان به جای نام آبجکت، مقدارnullرا به این متدها پاس داد.
سناریو کاربردی
در این آموزش، سناریوی کار با کلاسی به نام A بررسی شده است که دارای فیلدهایی با سطوح دسترسی مختلف (مانند firstName به صورت private و age به صورت public) است.
- دسترسی و خواندن: ابتدا با استفاده از
a.getClass()به شیءClassدسترسی پیدا میکنیم. برای فیلدهای عمومی ازgetFieldو برای فیلدهای خصوصی ازgetDeclaredFieldاستفاده میشود. اگر فیلد خصوصی باشد، حتماً بایدsetAccessible(true)فراخوانی شود، در غیر این صورت با خطایIllegalAccessExceptionمواجه میشویم. - تغییر مقدار (Modify): با استفاده از متد
setروی شیء فیلد، مقدار جدید را جایگزین میکنیم. برای مثال، مقدار فیلدfirstNameکهprivateوfinalبود و مقدار "Farzad" داشت، بدون وجود هیچ متد Setter و تنها با قدرت رفلکشن به "Ali" تغییر داده شد. این مثال نشان میدهد که رفلکشن چگونه میتواند کپسولهسازی (Encapsulation) را در جاوا نادیده بگیرد.
بیشتر بدانید
-
Handle Exceptions کار با رفلکشن همیشه نیازمند مدیریت Exceptionهای چک شده (Checked Exceptions) مانند
NoSuchFieldExceptionوIllegalAccessExceptionاست. همیشه کد خود را در بلوکهایtry-catchمناسب قرار دهید. -
Security Risks استفاده از رفلکشن برای تغییر فیلدهای
privateوfinalمانند یک شمشیر دو لبه است؛ این قابلیت بسیار قدرتمند است اما میتواند امنیت و پایداری کد را به خطر بیندازد. -
Static Final Fields تغییر دادن فیلدهایی که همزمان
staticوfinalهستند، بسیار دشوارتر است و معمولاً نیاز به روشهای هکگونه دارد که در شرایط عادی اصلاً توصیه نمیشود.
