Aceess Class Info with Reflection in Java
توضیحات جلسه
جزوه و مستندات
مفاهیم کلیدی
Reflection
قابلیتی در زبان جاوا که به برنامهنویس اجازه میدهد در زمان اجرا (Runtime)، ساختار کلاسها، متدها، فیلدها و سایر اجزای کد را بررسی کرده یا آنها را تغییر دهد.
Class Object
یک شیء مخصوص در حافظه که برای هر کلاس تعریفشده در جاوا ایجاد میشود. این شیء مانند یک «کارت شناسایی» عمل کرده و تمام اطلاعات مربوط به ساختار آن کلاس (Metadata) را در خود ذخیره میکند.
Metadata
اطلاعاتی که درباره خودِ کلاس وجود دارد؛ مانند نام کلاس، نام پکیج، لیست متدها، فیلدها، سازندهها (Constructors) و سطوح دسترسی (Modifiers).
Checked Exception
استثناهایی که در زمان کامپایل بررسی میشوند و برنامهنویس مجبور است آنها را مدیریت کند (مانند ClassNotFoundException هنگام استفاده از نام کلاس بهصورت رشته).
Modifier
کلمات کلیدی مانند public، private، final یا abstract که ویژگیها و سطوح دسترسی یک کلاس یا اعضای آن را تعیین میکنند. در رفلکشن، این مقادیر معمولاً بهصورت اعداد صحیح (Integer) برگردانده میشوند.
موارد مصاحبه ای
سه راه اصلی برای به دست آوردن Class Object چیست؟
۱. استفاده از متد getClass() روی یک آبجکت موجود.
۲. استفاده از پسوند .class بعد از نام کلاس (مثلاً Person.class).
۳. استفاده از متد استاتیک Class.forName() با دادن نام کامل کلاس (شامل پکیج) بهصورت رشته.
تفاوت بین getName() و getSimpleName() در کلاس چیست؟
متد getName() نام کامل کلاس را به همراه نام پکیج (Full Qualified Name) برمیگرداند، اما getSimpleName() فقط نام خود کلاس را بدون پکیج ارائه میدهد.
تفاوت متدهای getMethods() و getDeclaredMethods() در چیست؟
متد getMethods() فقط متدهای public کلاس و همچنین متدهای عمومی ارثبری شده از کلاسهای والد (مانند کلاس Object) را برمیگرداند. در مقابل، getDeclaredMethods() تمام متدهای تعریفشده در خودِ آن کلاس (شامل متدهای private) را برمیگرداند اما متدهای ارثبری شده را شامل نمیشود. این تفاوت در مورد Fields و Constructors نیز به همین صورت است.
چگونه میتوان متادیتاهای عددی (Modifiers) را به کلمات قابل فهم تبدیل کرد؟
خروجی متد getModifiers() یک عدد صحیح است. برای تبدیل این عدد به کلمات کلیدی جاوا، باید از متد استاتیک Modifier.toString(int) استفاده کرد.
چرا استفاده از Class.forName() نیاز به مدیریت Exception دارد؟
چون نام کلاس بهصورت یک رشته (String) به متد پاس داده میشود، احتمال اشتباه تایپی یا نبودن آن کلاس در مسیر پروژه وجود دارد؛ لذا جاوا ما را مجبور به مدیریت خطای ClassNotFoundException میکند.
سناریو کاربردی
در این آموزش، با استفاده از کلاسهایی به نام Person و A نشان داده شد که چگونه میتوان بدون داشتن دانش قبلی از محتوای یک کلاس در زمان کدنویسی، تمام جزئیات آن را در زمان اجرا استخراج کرد.
بهعنوان مثال، با فراخوانی متد getSuperclass() روی Class Object مربوط به کلاس Person مشاهده شد که اگر کلاسی بهطور صریح از جایی ارثبری نکند، والد مستقیم آن کلاس Object خواهد بود. همچنین با تعریف یک سازنده private در کلاس A و استفاده از getDeclaredConstructors()، توانستیم به سازندهای دسترسی پیدا کنیم که در حالت عادی و خارج از محیط رفلکشن، قابل مشاهده و دسترسی نیست. این سناریو نشان داد که رفلکشن چگونه میتواند لایههای امنیتی و دسترسیهای کلاس را برای بازرسی فنی باز کند.
بیشتر بدانید
نکته مدیریت خطا
هنگام کار با Class.forName()، اگر نام پکیج را بهدرستی وارد نکنید یا کلاس وجود نداشته باشد، برنامه با خطای ClassNotFoundException متوقف میشود. همیشه از نام کامل پکیج استفاده کنید.
نکته فنی در IDE
در محیطهایی مانند IntelliJ، زمانی که از متدهای رفلکشن استفاده میکنید، IDE به شما هشدار میدهد که متد موردنظر ممکن است وجود نداشته باشد (NoSuchFieldException یا NoSuchMethodException) و از شما میخواهد که کد را درون بلوک try-catch قرار دهید.
نکته بازرسی اعضا
اشیای برگرداندهشده از نوع Field یا Method خود دارای متدهای داخلی هستند که اجازه میدهند نوع بازگشتی (getReturnType) یا نوع پارامترهای ورودی را بهصورت دقیق بررسی کنید.
