



آیا دلتان برای بهروزرسانیهای دنیای توسعه نرمافزار تنگ شده است؟ اگر اینطور است، خوششانس هستید، چون امروز قرار است نگاهی به تمام اتفاقات جذابی بیندازیم که برای یکی از زبان های برنامهنویسی برتر دنیا در حال رخ دادن است.
با انتشار نسخه جدید Java 26، جاوا در حال تجربه یک تحول بزرگ است. اگر قابلیتهای جدید آن را دنبال نکرده باشید، چیزهای بسیار زیادی را از دست دادهاید.
شوخی را کنار بگذاریم؛ من واقعاً معتقدم جاوا در دهه آینده حتی ارزشمندتر خواهد شد، مخصوصاً زمانی که کدهای تولیدشده توسط مدلهای زبانی (LLM) رایجتر شوند.
این مقاله درباره ایجنتهای کدنویسی نیست، اما لازم است به یک نکته بسیار مهم درباره زبانهای برنامهنویسی اشاره کنم.
بعضی از افراد فوقثروتمند ادعا میکنند که طی ۶ تا ۱۲ ماه آینده، زبانهای برنامهنویسی منسوخ خواهند شد، زیرا مدلهای زبانی مستقیماً کد باینری تولید خواهند کرد. من معمولاً دوست ندارم خیلی صریح صحبت کنم، اما این حرف واقعاً بیمعنی است.
اول از همه، کد باینری بسیار حجیمتر از یک زبان برنامهنویسی سطح بالا است. بنابراین به دلیل حجم بیشتر دادهها، تعداد توکنهای بسیار بیشتری مصرف خواهد شد.
دوم اینکه انسانها نه میتوانند باینری را بخوانند، نه بنویسند و نه درک کنند. همچنین هیچ مزیت واقعی برای یک کسبوکار وجود ندارد که کنترل کامل نرمافزار خود را از دست بدهد.
اگر قرار باشد نتیجهای بگیریم، این است که زبانهای برنامهنویسی خوب امروز از همیشه مهمتر شدهاند.
احساس من این است که در آینده قابل پیشبینی، بیشتر ما کار را با دادن دستور به یک مدل زبانی آغاز میکنیم تا کدی در یک زبان برنامهنویسی سطح بالا و خوانا تولید کند؛ کدی که بهراحتی بتوان آن را اشکالزدایی و نگهداری کرد، و سپس با استفاده از کامپایلر، نسخه نهایی باینری تولید شود.
هیچ دلیلی نمیبینم که یک شرکت داوطلبانه مرحله دوم این فرآیند را حذف کند، زیرا این تنها راهی است که مطمئن میشود کاملاً به یک شرکت هوش مصنوعی برای ساخت محصول خود وابسته نیست.
پس باور کنید، زبانهای برنامهنویسی قرار نیست از بین بروند. حتی شرکتهایی مانند OpenAI نیز اکنون از زبانهایی مثل Rust حمایت میکنند و دقیقاً به همین دلیل است که جاوا ارزش دنبال کردن را دارد.
هیجانانگیزترین بخش، مسیر جدیدی است که این پلتفرم در پیش گرفته است.
جاوا در سه بخش بهبود یافته است:
همه این تغییرات در چارچوب جریان کاری جدید برنامهنویسی که کمی قبلتر درباره آن صحبت کردم، اهمیت بسیار زیادی دارند.
بیایید از خود زبان شروع کنیم.
نسخههای اخیر جاوا نوشتن برنامههای کوچک را بسیار سادهتر کردهاند. دیگر لازم نیست برای شروع یک برنامه، حجم زیادی کد اضافی بنویسید.
اکنون میتوانید یک فایل سورس فشرده با یک متد ساده void main بنویسید، آن را مستقیماً با دستور java اجرا کنید و از ورودی و خروجی پایه استفاده کنید، بدون اینکه لازم باشد استریمها را بهصورت دستی تنظیم کنید.
این قابلیت برای آموزش، اسکریپتنویسی، دموها و ابزارهای داخلی کوچک بسیار ارزشمند است.
جاوا همچنان یک زبان کامپایلشونده و با نوعدهی قوی است، اما تشریفات اضافی را در جاهایی که ارزشی ایجاد نمیکنند حذف کرده است.
بهبود دیگر، بدنه انعطافپذیر سازندهها (Constructor) است.
اکنون جاوا در موارد بیشتری اجازه میدهد قبل از فراخوانی super یا یک سازنده دیگر، دستوراتی اجرا شوند.
این یعنی میتوانید آرگومانها را اعتبارسنجی کنید، مقادیر موردنیاز را آماده کنید و فیلدها را مقداردهی اولیه کنید، سپس کنترل را به سازنده والد بسپارید.
این موضوع باعث میشود منطق سازندهها، بهخصوص در کدهایی که از وراثت زیاد استفاده میکنند، بسیار تمیزتر شود.
جاوا همچنین متغیرهای زیرخط (_) و الگوهای بدون نام را اضافه کرده است.
وقتی یک Lambda، Pattern یا Callback مقداری را در اختیار شما قرار میدهد که از آن استفاده نمیکنید، میتوانید آن را با یک زیرخط مشخص کنید.
این کار باعث میشود متغیرهایی که عمداً استفاده نمیشوند، از متغیرهایی که به اشتباه بدون استفاده ماندهاند، تفکیک شوند.
قابلیت جدید دیگر، وارد کردن ماژولها است.
بهجای اینکه کلاسها را یکییکی وارد کنید یا از Wildcard استفاده کنید، اکنون میتوانید API عمومی یک ماژول را وارد کنید.
برای مثال، با وارد کردن java.sql به کل API مربوط به SQL دسترسی خواهید داشت، بدون اینکه لازم باشد تکتک کلاسها را وارد کنید.
برای استفاده از این قابلیت نیز نیازی نیست برنامه خودتان ماژولار شده باشد.
اما تغییرات API بسیار اساسیتر هستند.
Stream Gatherers قابلیتهای جدیدی به Stream API اضافه میکنند و امکان تعریف عملیا ت میانی سفارشی را فراهم میسازند.
پیش از این، Streamها قدرتمند بودند اما بسته بودند؛ یعنی اگر عملیاتی که نیاز داشتید بهصورت داخلی وجود نداشت، مجبور بودید خیلی زود دادهها را Collect کنید، از reduce به شکل نامناسب استفاده کنید یا کدی بنویسید که خوانایی کمتری داشت.
Gathererها به توسعهدهندگان اجازه میدهند عملیات Stream قابل استفاده مجدد تعریف کرده و مستقیماً به Pipeline اضافه کنند.
Scoped Values بهعنوان جایگزینی بهتر برای ThreadLocal در بسیاری از کاربردها، مخصوصاً همراه با Virtual Threadها طراحی شدهاند.
آنها امکان نگهداری دادههای Context بهصورت تغییرناپذیر در یک محدوده مشخص را فراهم میکنند.
این قابلیت برای شناسه درخواست، اطلاعات رهگیری، Context مربوط به Tenant، Context کاربر و سایر دادههایی که باید در طول اجرای یک عملیات قابل خواندن باشند اما نباید بهصورت سراسری قابل تغییر باشند، بسیار مفید است.
Foreign Function & Memory API نیز یکی دیگر از بهروزرسانیهای مهم است.
این API جایگزینی مدرن برای JNI محسوب میشود.
اکنون کد جاوا میتواند از طریق یک API رسمی، توابع Native را فراخوانی کرده و با حافظه خارج از Heap کار کند.
این ویژگی هنگام کار با کتابخانههای خارجی، پایگاههای داده، Runtimeهای یادگیری ماشین، یکپارچهسازی سیستمها و کدهای حساس به کارایی که نیاز به تعامل با کد Native دارند، بسیار مفید است.
Class File API نیز راهکاری استاندارد در JDK برای خواندن، تغییر و نوشتن فایلهای Class جاوا ارائه میدهد.
این موضوع اهمیت زیادی دارد، زیرا بسیاری از فریمورکها به دستکاری Bytecode وابسته هستند.
فریمورکهایی مانند Spring، Hibernate و حتی ابزارهای تست معمولاً به کتابخانههایی مانند ASM وابسته بودند که با هر تغییر نسخه فایلهای Class جاوا باید بهروزرسانی میشدند.
اکنون با وجود Class File API در خود JDK، ابزارها میتوانند هماهنگی بسیار بهتری با نسخه جاوای مورد استفاده داشته باشند.
بهروزرسانیهای Runtime نیز به همان اندازه مهم هستند.
اکنون جاوا میتواند چند فایل سورس را مستقیماً اجرا کند، بدون اینکه به ساختار کامل Build نیاز باشد.
البته این قابلیت جای Maven را در پروژههای واقعی نمیگیرد، اما ساخت ابزارهای کوچک و انجام آزمایشها را بسیار آسانتر میکند.
اکنون میتوانید چند فایل جاوا بنویسید و مستقیماً اجرا کنید، بدون اینکه ابتدا ساختار کامل پروژه را ایجاد کنید.
Project Leyden نیز در حال بهبود زمان Startup و Warm-up از طریق کشکردن Ahead-of-Time است.
جاوا همواره در عملکرد نهایی بسیار قدرتمند بوده، زیرا کامپایلر JIT بر اساس رفتار واقعی برنامه بهینهسازی انجام میدهد.
اما نقطه ضعف آن همیشه زمان Startup و Warm-up بوده است.
AOT Caching بخشی از این پردازش را زودتر انجام میدهد؛ با اجرای یک مرحله آموزشی، اطلاعات مفید را ذخیره میکند تا اجرایهای بعدی سریعتر انجام شوند.
Compact Object Headers نیز سربار حافظه هر شیء را کاهش میدهند.
از آنجا که هر شیء مقداری Metadata برای JVM نگهداری میکند، کاهش این اطلاعات میتواند مصرف Heap را کاهش داده و دسترسی به Cache را بهبود دهد.
البته این موضوع ممکن است به محاسبات بیشتری نیاز داشته باشد، بنابراین نتیجه آن به نوع بار کاری بستگی دارد و معمولاً باید Benchmark انجام شود.
Generational ZGC نیز یکی از مهمترین پیشرفتهای Runtime است.
ZGC از قبل روی کاهش زمان توقف تمرکز داشت، اما نسخه Generational مدیریت اشیای کوتاهعمر را بسیار بهتر انجام میدهد؛ اشیایی که در برنامههای جاوا بسیار فراوان هستند.
جمعآوری زباله معمولاً همان بخشی است که باعث میشود عملکرد برنامه کمتر قابل پیشبینی باشد، زیرا گاهی رفتار آن شبیه یک دستگاه اسلات تصادفی است.
این موضوع اهمیت دارد، زیرا برنامههای مدرن حجم بسیار زیادی داده موقتی تولید میکنند.
تقریباً همه چیز در برنامه شما شیء ایجاد میکند: هر درخواست، Payloadهای JSON، Queryها، Pipelineهای Stream، Mapperها، تبدیل DTOها، لایه اعتبارسنجی، Context مربوط به Logging، اطلاعات Tracing و حتی لایههای انتزاعی معماری تمیز، همگی شیء تولید میکنند.
Garbage Collector باید تمام این حافظه را مدیریت کند.
از آنجا که GC مستقیماً بر تأخیر، توان عملیاتی، مصرف حافظه و هزینههای Cloud تأثیر میگذارد، طبیعتاً یکی از مهمترین بخشهای کل سیستم محسوب میشود.
Virtual Threadها نیز بهبود یافتهاند.
در Java 21، Virtual Threadها بسیار مفید بودند، اما مشکلی به نام Pinning وجود داشت؛ برخی عملیات باعث میشدند Thread اصلی (Carrier Thread) قفل شود و مقیاسپذیری کاهش پیدا کند.
در نسخههای جدید، Pinning مربوط به Object Monitor حذف شده و در Java 26 نیز Pinning ناشی از مقداردهی ا ولیه کلاسها کاهش یافته است.در نتیجه استفاده از Virtual Threadها در سناریوهای واقعی بسیار ایمنتر شده است.
اما جذابترین تغییرات، همان بهبودهای مربوط به کیفیت تجربه توسعهدهنده هستند.
جاوا ۲۶ توسعه قابلیت Pattern Matching را ادامه داده است.
اکنون Primitive Patternها امکان استفاده از Pattern Matching برای انواع اولیه را فراهم میکنند.
هدف این نیست که یک int به byte تبدیل شود، بلکه بررسی میشود که آیا یک مقدار مشخص از نوع int بدون از دست رفتن اطلاعات قابل نمایش در قالب byte هست یا نه.
برای مثال، مقدار صفر در یک byte جا میشود، اما عدد ۵۰۰ خیر.
همین ایده برای تبدیلهای عددی دیگر نیز کاربرد دارد؛ مثلاً بررسی اینکه آیا یک عدد صحیح بدون از دست رفتن اطلاعات قابل نمایش بهصورت float هست یا خیر.
این قابلیت باعث میشود Pattern Matching میان انواع مرجع و انواع اولیه سازگاری بیشتری داشته باشد.
Lazy Constants نیز یکی دیگر از قابلیتهای جذاب Java 26 هستند.
مقداردهی اولیه تنبل (Lazy Initialization) بسیار رایج است، اما پیادهسازی صحیح آن معمولاً نیازمند Double-Checked Locking، Synchronization، متغیرهای volatile و Getterهای دفاعی است.
Lazy Constants یک راهکار استاندارد برای این موضوع ارائه میکنند.
کافی است یک مقدار Lazy نهایی تعریف کنید، مقداردهنده اولیه را مشخص کنید و هر زمان لازم بود، متد get را فراخوانی کنید.
مقداردهنده حداکثر یک بار با موفقیت اجرا میشود.
مقادیر null پذیرفته نمیشوند و اگر مقداردهی اولیه شکست بخورد، در دسترسی بعدی دوباره تلاش خواهد شد.
از آنجا که این قابلیت توسط خود JVM پشتیبانی میشود، نسبت به پیادهسازیهای دستی امکان بهینهسازی بسیار بهتری را فراهم میکند.
علاوه بر آن، اکنون مجموعههای Lazy نیز در اختیار داریم؛ یعنی Listها و Mapها میتوانند عناصر خود را فقط هنگام دسترسی محاسبه کنند، در حالی که همچنان مانند List.of و Map.of غیرقابل تغییر باقی میمانند.
در لایه بالاتر، Java HTTP Client نیز از HTTP/3 پشتیبانی میکند که اتفاق بسیار مهمی است، زیرا HTTP/3 از پروتکل QUIC روی UDP استفاده میکند.در نتیجه Client باید رفتارهای متفاوت اتصال و انتخاب پروتکل را مدیریت کند.
برای مثال، ممکن است ابتدا با HTTP/2 شروع کند و بعد به HTTP/3 مهاجرت کند، یا هر دو را همزمان بررسی کند، یا ابتدا HTTP/3 را امتحان کرده و در صورت نیاز به HTTP/2 بازگردد، یا حتی فقط HTTP/3 را بپذیرد و در صورت پشتیبانی نشدن، عملیات را شکستخورده اعلام کند.
اما یکی از حوزههایی که جاوا همیشه به دشوار بودن آن معروف بوده، Concurrency است.
دلیلش هم این است که کتابهایی با بیش از ۴۰۰ صفحه فقط درباره همین موضوع نوشته شدهاند.
در مدل سنتی Concurrency در جاوا، ارسال Task، انتظار برای پایان آن، دریافت نتیجه و مدیریت خطا معمولاً در بخشهای مختلف کد پراکنده هستند.
به همین دلیل، سادهتر کردن Concurrency مدتهاست یکی از اهداف جاوا بوده است.Structured Concurrency دقیقاً برای همین منظور معرفی شده است.در این مدل، تمام کارهای همزمان در یک محدوده مشخص قرار میگیرند.
وظیفه والد یک Scope ایجاد میکند، زیرکارها را Fork میکند، منتظر پایان آنها میماند و نتیجه یا خطا را در همان بلوک مدیریت میکند.
هیچ زیرکاری نمیتواند پس از پایان Scope والد به اجرای خود ادامه دهد.این موضوع باعث میشود جریان کنترل واضحتر شود، مدیریت لغو عملیات و خطاها بهتر انجام شود و اشکالزدایی نیز آسانتر گردد، زیرا رابطه میان Threadها بهوضوح قابل مشاهده است.
همچنین این قابلیت در کنار Scoped Values بسیار خوب عمل میکند؛ بهطوریکه Context تعریفشده در Scope والد، بدون وابستگی به ThreadLocalهای قابل تغییر، بهصورت ایمن در اختیار Taskهای فرزند قرار میگیرد.
و در نهایت، جاوا در حال سختگیرتر شدن نسبت به Final Field Integrity است.
در حال حاضر Reflection میتواند فیلدهای final را تغییر دهد، موضوعی که فرضیات JVM درباره صحت و امکان بهینهسازی را تضعیف میکند.
اکنون جاوا به سمتی حرکت میکند که تغییر Reflective فیلدهای final فقط با مجوز صریح امکانپذیر باشد.البته این تغییر ممکن است روی برخی فریمورکها و کتابخانههایی که وابستگی زیادی به Reflection دارند تأثیر بگذارد، اما جهت حرکت کاملاً مشخص است و کلمه کلیدی final به تضمینی بسیار قویتر تبدیل خواهد شد.
در نتیجه، جاوا اکنون از همیشه قدرتمندتر است و اگر آن را جدی نگیرید، فرصت بزرگی را از دست میدهید.
به خاطر داشته باشید که Oracle سرمایهگذاری بسیار سنگینی روی هوش مصنوعی انجام داده است، اما با وجود این همچنان توسعه جاوا را در اولویت قرار داده است.
آنها میدانند زبانهای برنامهنویسی قرار نیست از بین بروند و هرچه یک زبان قدرتمندتر باشد، در عصر مدلهای زبانی شانس بیشتری برای مهمتر شدن خواهد داشت.
و قبل از اینکه مقاله را به پایان برسانیم، یک دانستنی جالب برای شما:
قبل از اینکه جاوا به زبان اپلتها، سیستمهای Enterprise و نرمافزارهای مالی تبدیل شود، نام آن Oak بود و از پروژه Green شرکت Sun Microsystems به وجود آمد.
نکته جالبتر این است که هدف اولیه آن اصلاً وب نبود، بلکه لوازم الکترونیکی مصرفی بود.
در سال ۱۹۹۲، این تیم اولین کنترلر واقعی لمسی دستی به نام Star 7 را ساخت.
اینجاست که شخصیت Duke وارد داستان میشود.
Duke یک عامل نرمافزاری متحرک بود که توسط هنرمندی به نام Joe Palrang طراحی شد تا کاربران را در رابط کاربری راهنمایی کند.
میتوان آن را پیشدرآمدی برای شخصیت Clippy مایکروسافت دانست.
اما نکته بامزه اینجاست که Duke روی یک Thread مستقل و ناهمزمان اجرا میشد و در سطحی پایینتر از برنامههای اصلی سیستم فعالیت میکرد.
بنابراین اگر برنامه اصلی روی Star 7 هنگ میکرد، کند میشد یا هنگام بارگذاری برنامه با مشکل مواجه میشد، Duke همچنان کاملاً روان حرکت میکرد.
او برای کاربر دست تکان میداد، پشتک میزد یا اطراف صفحه را نگاه میکرد، بدون اینکه کوچکترین تأثیری از خراب شدن سیستم در پشت صحنه بپذیرد.
هدف از این کار، ایجاد این تصور بود که همه چیز کاملاً روان و بدون مشکل کار میکند، حتی روی سختافزارهای بسیار ضعیف آن زمان.
اگر از این مقاله خوشتان آمد، میتوانید به جامعه جاواپرو بپیوندید؛ جایی که محتوای تخصصی بیشتری منتشر میکنم.
لطفاً نظرتون رو در مورد این مقاله در زیر کامنت کنید، از اینکه مقاله را تا اینجا مطالعه کردید متشکرم.
بستن *نام و نام خانوادگی * پست الکترونیک * متن پیام |
دوره های آموزشی برنامه نویسی
انجام پروژه های برنامه نویسی
تدریس خصوصی برنامه نویسی
بیش از 10 سال از فعالیت جاواپرو میگذرد
جاواپرو دارای مجوز نشر دیجیتال از وزارت فرهنگ و ارشاد اسلامی می باشد
جهت ارتباط مستقیم با جاواپرو در واتساپ و تلگرام :
09301904690
بستن دیگر باز نشو! |


![جهت اطلاع از آموزش ها و اطلاع رسانی های جاواپرو عضو کانال بله شوید[ اینجا کلیک کنید]](https://dl.javapro.ir/image/marketing/javapro_bale3.png)
![مشاهده دوره های مرتبط با جاوا ، Spring و میکروسرویس[کلیک کنید]](https://dl.javapro.ir/image/marketing/esf_co.png)
![مشاهده جزییات و سرفصل های دوره Spring Batch [اینجا کلیک کنید]](https://dl.javapro.ir/spring_batch/springbatchpop4.jpeg)


![مشاهده سرفصل ها و ثبت نام در دوره Spring Boot جاواپرو [کلیک کنید]](https://dl.javapro.ir/image/marketing/banerday1403springboot.png)
























.png)
-min.png)
-min.png)
-min.png)


-min.png)









-min.png)

.jpg)


