یک شرکت نرمافزار بانکی در تهران انبار قطعات دستگاههای خودپرداز را نگه میدارد. در جاوای امروز، چیزی که شمرده میشود یک سطر است:
record Ghete(String kod, int mojoodi) {}
یک record سازنده و equals و hashCode و toString را برای شما مینویسد، که چهل تا شصت سطر است که قبلاً یا تایپ میشد یا ویرایشگر تولیدش میکرد و بعد بیصدا با بقیه ناسازگار میشد. دسترسیگرِ یک record بهشکل kod() است نه getKod()، که اولین چیزی است که به چشم هرکسی که جاوا را پیش از ۲۰۲۱ یاد گرفته غلط میآید. و یک record بهشکل Ghete[kod=PL-14, mojoodi=3] چاپ میشود، پس فهرستی از آنها بدون نوشتن هیچ چیزی در لاگ خواندنی است.
جمع زدن موجودی روی سطرهای تکراری بعدش یک حلقه است:
var ghetat = List.of(new Ghete("PL-14", 3), new Ghete("RB-02", 0), new Ghete("PL-14", 5));Map<String, Integer> jam = new HashMap<>();for (Ghete g : ghetat) jam.merge(g.kod(), g.mojoodi(), Integer::sum);
jam.merge(kelid, meghdar, Integer::sum) به یک کلید اضافه میکند، چه باشد چه نباشد، و همان بررسی containsKey را حذف میکند که هر آموزش جاوای نوشتهشده پیش از ۲۰۱۴ با آن شروع میشود. دو نام دیگر روی همان سطر هم زود دانستنشان میارزد: var نوع یک متغیر محلی را استنتاج میکند و در زمان اجرا هیچ چیز را عوض نمیکند، و List.of یک فهرست تغییرناپذیر برمیگرداند و add روی آن استثنا میدهد، که کسانی را میگیرد که انتظار دارند فهرست، فهرست باشد.
انتخاب نگاشت یک تصمیم است، نه یک پیشفرض
HashMap ترتیب ندارد و TreeMap بر اساس کلید مرتب میکند، و در میانهشان LinkedHashMap ترتیب درج را نگه میدارد. گزارش موجودی آن شرکت هر بار با ترتیب دیگری بیرون میآمد تا وقتی HashMap به TreeMap تبدیل شد، و نه پیش از آن چیزی خراب بود و نه بعدش؛ نسخه اول هرگز قول ترتیبی نداده بود و آدمها فرضش کرده بودند. جاوا این پرسش را بلند میپرسد، جایی که زبانهای دیگر خودشان جوابش را میدهند، و مجبور شدن به جواب دادن بیشترِ استدلالِ له آن پرحرفی است. مجموعه کامل و تفاوتهایشان فهرست، نگاشت و مجموعه، و انتخاب میانشان است.
بقیه زبان متعارف است و کم هم نیست: کلاس، پکیج، رابط، و چیدمان فایلی که ابزار ساخت اجبارش میکند نه پیشنهادش. آن نحو، نوعها و JVM زیرشان است، و قراردادهای نامگذاری و کتابخانهای که با آن میآیند کلاسها، پکیجها و کتابخانه استاندارد.
زبان، همان سکو نیست
JVM کاتلین و اسکالا و کلوژر را هم اجرا میکند، و جاوا یکی از زبانهای روی آن است. این نکتهای عملی است نه یک اطلاع عمومی: تیمی که به کاتلین میرود هر کتابخانه، هر گام ساخت و هر روال استقرار را نگه میدارد و فقط فایلها را عوض میکند. همین هم دلیل این است که افزودههای خود جاوا آهسته و با احتیاط میآیند، چون چیزی که زیرش هست قراردادی است که چهار زبان و سی سال سیستم در حال کار به آن وابستهاند.
تزریق وابستگی
سه چیزی که فقط با هم میچرخند
کد شما هیچوقت شیای را که به کار میبرد خودش نمیسازد، و همین چیدمان تمام کاری است که Spring پیش از اجرای هر چیزی انجام میدهد.
- رابط
- پیادهسازی
- ظرف
- رابطچیزی که کد میخواهد، با نوعش
- پیادهسازیچیزی که واقعاً تحویل داده میشود، انتخابشده موقع بالا آمدن نه داخل کد
- ظرفانوتیشنها را میخواند و آن تحویل دادن را انجام میدهد
همین هم دلیل این است که خرابی بخش آخر، اسم کلاسهایی را میآورد که کسی ننوشته. یکی از این چرخها را بچرخانید و آن دوتای دیگر از قبل حرکت کردهاند، پیش از اولین سطر کد خودتان.
ابزار، و سالی که این حرف درست است
نسخه پشتیبانیبلندمدت جاری، Java 25 است که در سپتامبر ۲۰۲۵ آمد، و بیشتر کدهای در حال کار امروز روی Java 21 هستند که از سپتامبر ۲۰۲۳ است. اما در ایران عدد سومی هم مهم است: بخش بزرگی از کد سازمانی و بانکی هنوز روی Java 8 اجرا میشود، چون ارتقا در سیستمی که ممیزی شده تصمیم فنی نیست. اگر سر کار با Java 8 روبهرو شدید، هیچکدام از سه چیز بالای این صفحه آنجا نیست: نه record، نه var، و نه سوییچ تازه.
Spring Boot از سال ۲۰۱۴ و رایگان، همان است که شکل شغل را عوض کرد. جای پیکربندی XML و مستقر کردن یک فایل بستهبندیشده داخل یک سرور برنامه جدا را گرفت که یک نفر دیگر مدیریتش میکرد: Spring Boot سرور خودش را بالا میآورد، پس سرور برنامهای برای مستقر شدن در آن وجود ندارد، و کل چیز یک فایل قابل اجراست. تقریباً هر آگهی استخدامی که بنویسد جاوا، منظورش همین است.
Maven و Gradle دو ابزار ساختاند، هر دو رایگان، و جای کامپایل دستی و نگه داشتن پوشهای از فایلهای jar را گرفتند. کدامشان، پیش از رسیدن شما تصمیم گرفته شده و ارزش نظر دادن ندارد.
اولین روز کار با هرکدامشان در ایران هم معمولاً سر همین میگذرد: یک ساخت تازه صدها artefact از مخزن مرکزی میگیرد، و آن اتصال همان جایی است که میایستد. جوابش یک بار تنظیم کردن نشانی آینه در فایل تنظیمات ابزار ساخت است، نه بارگیری دستی jarها، که کار همیشگیای است که سالها انجام شده و هیچوقت کامل نمیشود.
اشتباه: خواندن سطر اول یک خرابی بالا آمدن
جایی که آدمها واقعاً میایستند اینجاست، و سمیکالنها نیستند. اولین برنامه Spring که بالا نمیآید چهل قاب چاپ میکند که هیچکدامشان اسم فایلی را که خودتان نوشتهاید نمیآورد، و سطر بالایی میگوید یک bean ساخته نشد. از بالا بخوانیدش نامفهوم است. اطلاعات در پایین است: چند بلوک که هرکدام با Caused by شروع میشوند، و آخری همان مسئله اصلی است، که معمولاً چیز کوچکی است مثل یک تنظیم جاافتاده یا دو کلاس که هر دو داوطلب یک وابستگی شدهاند.
پس عادتش این است که اول به آخرین Caused by بروید و از آنجا به بالا بخوانید، که دقیقاً برعکس روش خواندن ردپای خطای پایتون است و یک بار سر همه را میبرد. فریمورکی که آن ردپا را تولید کرده و دلیل اینکه اصلاً دارد سیمکشی میکند فریمورکی که بیشتر شغلهای جاوا واقعاً منظورشان است است.
چیزی که این صفحه تعیین نمیکند این است که سرویس بعدی را روی همین سکو با کدام زبان بنویسید، که انتخابی واقعی است و زیر زبانهای برنامهنویسی نشسته. چیدمانی که Spring رویش ساخته شده و دلیل اینکه رابطی با یک پیادهسازی اینجا عادی است و جای دیگر مشکوک، برنامهنویسی شیگرا است، و کاری که سرویس حاصل واقعاً انجام میدهد زیر وب است.