جافا لا تموت - بل تولد من جديد
\nكل عام يكتب أحدهم "جافا ميتة". وفي كل عام تثبت جافا العكس. في عام 2025، تحصل اللغة التي تبلغ من العمر 30 عامًا تقريبًا على العديد من التحديثات الأساسية. إذا كنت تكتب بلغة جافا ولكن آخر مرة اطلعت فيها على سجل التغييرات (changelog) كانت قبل عام - فقد تأخرت بالفعل. دعنا نستعرض بالتفصيل ما الذي سيتغير تحديدًا وكيف ستؤثر هذه التغييرات على كودك.
\nلن أثقل عليك بالمواصفات الجافة. بدلاً من ذلك - أمثلة حقيقية يمكنك تشغيلها اليوم (تقريبًا). هيا بنا.
\n\nالخيوط الافتراضية (Project Loom) - نهاية عصر الحظر
\nهذا هو التغيير الأكبر على الأرجح. الخيوط الافتراضية (virtual threads) هي خيوط خفيفة الوزن تسمح بكتابة كود غير متزامن بأسلوب متزامن. في عام 2025، تصبح أخيرًا مستقرة وموصى بها للإنتاج.
\nسابقًا، كنت تكتب شيئًا مثل:
\nExecutorService executor = Executors.newFixedThreadPool(10);\nexecutor.submit(() -> {\n // استدعاء حظر\n String result = restTemplate.getForObject(url, String.class);\n return result;\n});\nالمشكلة هي أن كل خيط هو كائن ثقيل. 10 خيوط - لا بأس، 10,000 - مشكلة بالفعل. مع الخيوط الافتراضية، يمكنك تشغيل ملايين الخيوط دون القلق بشأن الذاكرة:
\ntry (var executor = Executors.newVirtualThreadPerTaskExecutor()) {\n for (int i = 0; i < 100_000; i++) {\n executor.submit(() -> {\n // الآن هذا خفيف الوزن\n String result = restTemplate.getForObject(url, String.class);\n return result;\n });\n }\n}\nالفرق الرئيسي: الخيوط الافتراضية غير مرتبطة بخيوط نظام التشغيل. عندما يتم حظر خيط (على سبيل المثال، في الإدخال/الإخراج I/O)، تقوم JVM ببساطة بتبديله إلى خيط افتراضي آخر. لا تكاليف إضافية.
\nماذا يعني هذا لك؟ انسَ أطر العمل غير المتزامنة المعقدة مثل CompletableFuture والمكتبات التفاعلية. في عام 2025، سيكون الكود المتزامن القياسي على الخيوط الافتراضية أسرع وأبسط.
\n\nكيفية الترحيل
\nاستبدل newFixedThreadPool بـ newVirtualThreadPerTaskExecutor. إذا كنت تستخدم Spring Boot - قم بالتحديث إلى الإصدار 3.2+، فهو يدعم ذلك بالفعل. فقط تأكد من أن مكتباتك لا تستخدم synchronized في الأقسام الحرجة - هذه هي النقطة الوحيدة التي قد تعلق فيها الخيوط الافتراضية.
مطابقة الأنماط (Pattern Matching) و Switch - الكود يصبح أقصر
\nفي عام 2025، وصلت مطابقة الأنماط إلى switch و instanceof. الآن بدلاً من مجموعة من if-else المتداخلة، يمكنك الكتابة بشكل موجز وقابل للقراءة.
كان (النمط القديم):
\nif (obj instanceof String) {\n String s = (String) obj;\n System.out.println(s.length());\n} else if (obj instanceof Integer) {\n Integer i = (Integer) obj;\n System.out.println(i * 2);\n}\nأصبح (جافا 21+):
\nswitch (obj) {\n case String s -> System.out.println(s.length());\n case Integer i -> System.out.println(i * 2);\n case null -> System.out.println("null");\n default -> System.out.println("unknown");\n}\nلاحظ case null - هذا تحسين منفصل. سابقًا، كان switch يرمي NullPointerException عند تمرير null. الآن يمكن معالجة ذلك بشكل صريح.
ميزة رائعة أخرى - record patterns. إذا كان لديك record:
\nrecord Point(int x, int y) {}\nفيمكنك الكتابة:
\nif (obj instanceof Point(int x, int y)) {\n System.out.println("x=" + x + ", y=" + y);\n}\nبدون تحويل أنواع إضافي. في عام 2025، سيكون هذا هو التيار الرئيسي - استخدمه لجعل الكود أنظف.
\n\nجمع القمامة: ZGC و Generational GC
\nفي عام 2025، أصبح جمع القمامة أسرع. ZGC (Z Garbage Collector) أصبح الآن مفعلًا افتراضيًا لمعظم التطبيقات.