Reflection آچار فرانسه ای در جاوا

امروز می خوام یه آچار فرانسه رو توی جاوا بهتون معرفی کنم به اسم Reflection که حتما بهش برخوردید ولی احتمالا بهش توجه نکردید، در وهله ی اول یه توضیح مختصر در موردش میدم و یه راست میرم سراغ پروژه ی عملی تا حوصلتون سر نره، بعد کاملش می کنمReflection چیه؟رفلکشن یه کلاس توی جاوا هست که به کمکش می تونید در زمان اجرای کد،اطلاعاتی از ساختار Class، Field، Interface، Annotation و همچنین Method رو بدست بیارید یا حتی اون ساختار رو تغییر بدیدمثلا: متد X چه ورودی هایی داره، چه خروجی ای داره، اسمش چیه، متد رو فراخوانی کنیمکلاس Y چه متد هایی داره، چه فیلد هایی داره، چه سازنده هایی داره، یه شی از کلاس بسازیمپروژه ی عملیفرض کنید برنامه ای داریم به شکل زیر https://gist.github.com/AliRezaBeigy/15df617eb728902efd52e2ab83e8176f خب حالا می خواید توی این چالش برنده بشید، مشخصه برای برنده شدن دو تا راه داریدمقدار فیلد challengeDone رو true کنیدبرید تو آدرس متد CheckChallenge داخل مموری کاری کنید که وقتی این متد صدا زده شد یه متد دیگه که شما می خواید اجرا شهبنظر راه اول اینجا هم راحت تره هم توی بحث امروز بیشتر می گنجه D:برای اینکه مقدار اون فیلد رو عوض کنیم راه مستقیم نداریم چون دسترسی اون فیلد private هست پس باید با Reflection وارد عمل بشیمکارهایی که باید بکنیم به شرح زیرهکلاس هدف رو انتخاب کنیم، به سه روش زیر میشه عمل کرد https://gist.github.com/AliRezaBeigy/5af5f16541d00fa91bb6463b08868ff6 فیلد challengeDone رو بدست بیاریم https://gist.github.com/AliRezaBeigy/79962e60ec50a42a8b042059d0a5ad44 دسترسی به فیلد private رو آزاد کنید https://gist.github.com/AliRezaBeigy/eb818babe5e03206a00daaf336623378 مقداری که مد نظر داریم رو ست می کنیم https://gist.github.com/AliRezaBeigy/92e5e31dfc65d81d715c2ff900d6dde0 خروجی نهایی: https://gist.github.com/AliRezaBeigy/5967592fb18c14ad2b3e1d9359e1deee توضیحات تکمیلیدر قدم اول ما کلاس هدف مون رو بدست آوردیم، سه تا راه وجود داره که از راه سوم می تونید برای زمانی استفاده کنید که کلاس مورد نظر به صورت عادی در دسترسی نباشه مثل JDBC driver ها یا زمانی که می خواید برنامه زمان دیکامپایل شدن تشخیص فراخوانی یک متد به راحتی صورت نگیرهدر قدم دوم فیلد مورد نظرمون رو داخل اون کلاس پیدا میکنیم ، سوالی که ممکنه براتون پیش بیاد اینه که فرق متد getDeclaredField با متد getField در چیه، باید عرض کنم متد getField تنها فیلد هایی رو بر می گردونه که public باشنددر قدم سوم چون فیلد private هست ما باید دسترسی به فیلد رو آزاد کنیم تا بتونیم داخلش مقداری رو ست کنیم، نکته ای که باید بهش اشاره کنم اینه که حتی اگر مطمئن هستید که فیلد شما public هست حتما دسترسی فیلد رو آزاد کنید چون ممکنه بخواید از برنامه خروجی بگیرید و از یه Optimizer مثل R8، Proguard استفاده کنید که ممکنه باعث بشه زمان کامپایل modifier فیلد مد نظرتون private بشهدر قدم چهارم حواستون باشه ما با کلاس ReflectionGame کار داشتیم ن با یک شی از اون پس وقتی می خواید از متد set فیلد استفاده کنید باید بهش اون آبجکت که شامل اون فیلد میشه رو بدید و بگید چه مقداری داخلش ست کنهکاربرد های دیگری از Reflectionگرفتن متد سازنده ی یک Class https://gist.github.com/AliRezaBeigy/aeac1531f24ae502c2c0fd1d3d09f105 می تونید متد سازنده ی کلاس رو با توجه به Signatureش بدست بیاریدبه اینجا مراجعه کنیدساخت شی از Class https://gist.github.com/AliRezaBeigy/314cea23e0e1108fd34688360b7c83f4 فراخوانی غیر مستقیم Method https://gist.github.com/AliRezaBeigy/93a15db51d64a0a53c2ce4b561297499 برررسی interface بودن یا نبودن یک Class https://gist.github.com/AliRezaBeigy/5197cbf19dea1d112331d3150ec6c279 رفرنس هاReflection in JavaJava Reflection API