Farzad Afi Logo

FarzadAfi

آموزش تخصصی برنامه نویسی

Generic WildCard

📖توضیحات درس

🎥 آموزش جاوا – قسمت هفتاد و نهم از بوت‌کمپ رایگان جاوا 📚 Generics in Java – Wildcards & Invariance Explained در چهارمین ویدیو از پلی‌لیست جنریک در جاوا، می‌ریم سراغ یکی از مفاهیم بسیار مهم و کاربردی دنیای Generics: 🎯 WildCardها و همچنین مفهوم کلیدی Invariance. اگر همیشه این سؤال برات پیش اومده که: «چرا لیستی از رشته ها قابل جایگزینی با لیستی از آبجکت ها نیست؟» یا «Wildcard دقیقاً چطور کار می‌کنه و در چه مواقعی باید ازش استفاده کنیم؟» این جلسه دقیقاً همون چیزیه که دنبالش بودی! در این ویدیو بررسی می‌کنیم: ✨ مرور سریع جلسه قبل (Recap) برای اینکه ذهن کاملاً گرم بشه، یک مرور کوتاه از جلسات قبلی جنریک داریم. 🧩 طرح یک مسئله واقعی (Problem) برای درک بهتر WildCard، یک سناریو واقعی ارائه می‌کنیم که دلیل نیاز به WildCardها را کاملاً روشن می‌کند. 🎛️ مفهوم مهم Invariance یاد می‌گیریم چرا جنریک‌ها در جاوا Invariant هستند و این موضوع چه تأثیری در کدنویسی ما دارد. 🌀 ورود به WildCardها (?) با WildCard آشنا می‌شیم؛ اینکه چطور تعریف می‌شود و چه کاربردهایی دارد. 💡 مزایا و فواید WildCardها (Benefits) بررسی می‌کنیم WildCardها چطور کد ما را منعطف‌تر، امن‌تر و قابل‌گسترش‌تر می‌کنند. ⚠️ محدودیت‌ها (Limitations) در کنار مزایا، محدودیت‌های استفاده از WildCardها را هم یاد می‌گیریم تا در عمل اشتباه نکنیم. 🔁 مرور نهایی (Review) در پایان جلسه یک مرور کلی داریم تا نکات مهم کاملاً تثبیت شوند. لینک داکیومنت تدریس: https://github.com/farzadafi/ProgrammingByFarzadAfi/tree/master/document/generic 💬 گروه پرسش و پاسخ تلگرام: @programmingByFarzadAfi 💬 گروه پرسش و پاسخ بله: @programming_by_farzadafi هر سؤالی داشتی، می‌تونی داخل گروه بپرسی؛ من یا مربی‌های گروه در سریع‌ترین زمان کمکت می‌کنیم 💬 🎯 بوت‌کمپ رایگان جاوا – آموزش پروژه‌محور برای یادگیری اصولی و ورود به بازار کار
00:18:22🎯رایگان

📄جزوه

مفاهیم کلیدی

  • Generic مکانیزمی در زبان جاوا که اجازه می‌دهد کلاس‌ها، اینترفیس‌ها و متدها با انواع داده‌های مختلف (Types) به صورت پارامتریک کار کنند. هدف اصلی آن بررسی نوع داده در زمان کامپایل و جلوگیری از خطاهای زمان اجراست.

  • Invariance یک ویژگی در جنریک‌های جاوا که طبق آن، رابطه‌ی ارث‌بری بین انواع داده (مثلاً String فرزند Object است) به نسخه‌ی جنریک آن‌ها منتقل نمی‌شود. به زبان ساده، List<String> فرزندِ List<Object> نیست.

  • Wildcard (?) یک علامت سوال (?) که در جنریک‌ها به عنوان یک جایگاه نامشخص (Placeholder) برای انواع داده عمل می‌کند. زمانی استفاده می‌شود که نوع دقیق داده برای ما اهمیتی ندارد یا می‌خواهیم متدی بنویسیم که با هر نوع ورودی کار کند.

  • Type Safety اطمینان از اینکه عملیات روی داده‌ها با نوع صحیح انجام می‌شود. جنریک‌ها با انتقال بررسی‌ها به زمان کامپایل، امنیت کد را بالا برده و از خطاهایی مانند ClassCastException جلوگیری می‌کنند.

  • Compile-time vs Runtime Checking قبل از جنریک‌ها، بررسی نوع داده در زمان اجرا (Runtime) انجام می‌شد که منجر به کرش کردن برنامه می‌شد. با جنریک‌ها، کامپایلر مثل یک دستیار در زمان کدنویسی خطاها را شناسایی می‌کند.


موارد مصاحبه ای

  • چرا در جاوا نمی‌توان List<String> را به List<Object> نسبت داد؟ به دلیل خاصیت Invariance. اگر جاوا این اجازه را می‌داد، امنیت نوع داده (Type Safety) به خطر می‌افتاد؛ زیرا می‌توانستیم در لیستی که در اصل برای String ساخته شده، یک مقدار Double قرار دهیم و این موضوع باعث بروز فاجعه در زمان اجرا می‌شد.

  • تفاوت اصلی Wildcard با استفاده از Type Parameter (مانند <T>) چیست؟ استفاده از Wildcard ساده‌تر است و خوانایی کد را بالا می‌برد. زمانی که در بدنه متد نیازی به ارجاع به نام نوع داده نداریم و صرفاً می‌خواهیم یک عملیات عمومی (مثل چاپ کردن) انجام دهیم، Wildcard انتخاب بهتری است.

  • محدودیت اصلی استفاده از وایلد کارت علامت سوال (?) چیست؟ هنگام استفاده از List<?> ما فقط مجاز به خواندن (Read) از لیست هستیم. به دلیل اینکه کامپایلر نوع دقیق داده‌های درون لیست را نمی‌داند، اجازه اضافه کردن (Write) هیچ مقداری (به جز null) را به ما نمی‌دهد تا امنیت برنامه حفظ شود.


سناریو کاربردی

فرض کنید می‌خواهید متدی بنویسید که هر لیستی (شامل اعداد، رشته‌ها یا اشیاء کاستوم) را دریافت کرده و محتویات آن را چاپ کند.

۱. تلاش اول (اشتباه): اگر ورودی متد را List<Object> تعریف کنید، کامپایلر اجازه نمی‌دهد یک List<String> یا List<Integer> به آن پاس دهید، چون آن‌ها را ساب‌کلاسِ لیستِ آبجکت نمی‌داند.

۲. تلاش دوم (درست با Wildcard): اگر ورودی متد را به صورت List<?> تعریف کنید، این متد اصطلاحاً انعطاف‌پذیر (Flexible) می‌شود. حالا می‌توانید هر لیستی با هر نوع داده‌ای را به آن بدهید. متد به راحتی روی لیست پیمایش کرده و آیتم‌ها را چاپ می‌کند، اما اجازه ندارد عضو جدیدی به این لیست اضافه کند.


بیشتر بدانید

  • نکته کتابخانه‌ای در کدهای داخلی جاوا، کلاس Collections در متدهایی مانند copy و sort به طور گسترده از وایلد کارت‌ها استفاده کرده است تا انعطاف‌پذیری لازم برای کار با انواع کالکشن‌ها را داشته باشد.

  • فلسفه طراحی وایلد کارت‌ها برای حل محدودیت‌های ناشی از Invariance معرفی شدند تا همزمان با حفظ امنیت کامل (Type Safety)، امکان نوشتن کدهای چندمنظوره و پویا فراهم شود.

  • نکته فنی فراموش نکنید که علامت سوال (?) به تنهایی به معنای "هر چیزی" است، اما در جلسات پیشرفته‌تر خواهید دید که می‌توان آن را با کلمات کلیدی extends و super محدود کرد (Bounded Wildcards).