مقالات معمّقة حول التكنولوجيا التي تشكّل المستقبل.

جافا تتحسن باستمرار ولا أحد يلاحظ

إيقاع الإصدارات كل ستة أشهر غيّر جافا بهدوء. مطابقة الأنماط والخيوط الافتراضية والـ Records جعلتها لغة مختلفة تماماً.

فنجان قهوة متوهج بينما يتحول مكتب قديم كئيب إلى مساحة حديثة مشرقة

جافا هي «روداني دانجرفيلد» لغات البرمجة: لا تحظى بالاحترام الذي تستحقه. اذكر جافا أمام معظم المطورين دون سن الثلاثين وسيتخيلون ملفات إعدادات XML و Enterprise Beans و AbstractSingletonProxyFactoryBean. سمعة اللغة تجمدت عند عام 2008، حين كانت Java 6 أحدث إصدار، وكانت كتابة جافا تعني الغرق في الكود النمطي المتكرر.

لكن شيئاً مدهشاً حدث منذ أن تبنت جافا دورة إصدارات كل ستة أشهر في 2017. تطورت اللغة بوتيرة كانت ستبدو مستحيلة خلال الفجوات التي دامت أربع سنوات بين Java 6 و7 و8. Records. Sealed classes. Pattern matching. Virtual threads. String templates. Structured concurrency. كل إصدار يضيف ميزات تجعل كود جافا أقصر وأكثر تعبيراً وأمتع في الكتابة. و Java 26 يواصل هذا المسار، والفجوة بين «جافا كما هي» و«جافا كما يتخيلها الناس» لم تكن أوسع من أي وقت مضى.

الميزات التي غيّرت كل شيء

إذا لم تكتب جافا منذ Java 8، فأنت تفوّت عقداً كاملاً من التحسينات. إليك شكل اللغة اليوم.

Records (Java 14) هي فئات بيانات غير قابلة للتغيير. ما كان يتطلب 50 سطراً من الكود النمطي المتكرر — الحقول والمُنشئ والـ getters وequals وhashCode وtoString — أصبح سطراً واحداً.

// Java 8: 50 lines of boilerplate
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point)) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() { return Objects.hash(x, y); }
@Override
public String toString() { return "Point[x=" + x + ", y=" + y + "]"; }
}
// Java 14+: one line
record Point(int x, int y) {}

Pattern matching (من Java 16 إلى 21، ولا يزال في تطور) يتيح لك تفكيك الكائنات داخل تعبيرات switch وفحوصات instanceof. وهذا يلغي سلاسل if-else-instanceof المتداخلة التي كانت تُثقل كود جافا.

// Pattern matching with sealed types and records
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}
// Exhaustive pattern matching — compiler verifies all cases covered
double area(Shape shape) {
return switch (shape) {
case Circle(var r) -> Math.PI * r * r;
case Rectangle(var w, var h) -> w * h;
case Triangle(var b, var h) -> 0.5 * b * h;
};
}

Virtual threads (Java 21) خيوط خفيفة الوزن تديرها JVM بدلاً من نظام التشغيل. يمكنك إنشاء ملايين منها دون أن تنفد الذاكرة أو مقابض خيوط نظام التشغيل. وهذا يجعل نموذج «خيط واحد لكل طلب» — وهو أبسط نموذج للتزامن — عملياً على نطاق واسع.

// Create a million concurrent tasks — try this with OS threads
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 1_000_000).forEach(i -> {
executor.submit(() -> {
// Each task gets its own virtual thread
// Blocking I/O (HTTP, DB, file) automatically yields
var response = httpClient.send(request, BodyHandlers.ofString());
return response.body();
});
});
}
// All done — executor auto-closes, waits for completion

الـ Virtual threads هي إجابة جافا على goroutines في Go وcoroutines في Kotlin. الفرق أنك لا تحتاج إلى صياغة خاصة أو تلوين دوالك. الكود المتزامن (blocking) العادي يعمل — تعلّق JVM الخيوط الافتراضية وتستأنفها عند نقاط الحجب بشفافية. عميل HTTP المتزامن وJDBC driver وكود الإدخال والإخراج للملفات الحالي يستفيد منها دون أي تعديل.

لماذا لا أحد يلاحظ؟

مسار تحسن جافا مثير للإعجاب فعلاً. فلماذا لا تزال الصورة الذهنية عالقة في 2008؟

أولاً، الجمود المؤسسي. تشغّل منظمات كثيرة Java 8 أو 11 لأن ترقية قاعدة كود ضخمة مكلفة ومحفوفة بالمخاطر. وعندما يتحدث المطورون عن «جافا»، فهم يقصدون النسخة التي تستخدمها شركتهم، لا أحدث إصدار. مطورو Java 8 لم يجربوا Records ولا pattern matching ولا virtual threads.

ثانياً، طبقة الأطر. تضيف Spring Boot وJakarta EE وأطر المؤسسات الأخرى تعقيداً خاصاً فوق اللغة. يلوم المطورون «جافا» على طقوس الـ annotations في Spring، لكن ذلك من الإطار لا من اللغة. جافا الحديثة بدون إطار ثقيل خفيفة بشكل مدهش.

ثالثاً، الزخم الثقافي. تنسب ثقافة التقنية اللغات إلى «قبائل». جافا هي لغة «المؤسسات»، مرتبطة بالشركات الكبرى والإجراءات البيروقراطية والإفراط في الهندسة. هذه السمعة استحقتها — فتطوير جافا حوالي 2005 كان يستحق النقد. لكن السمعة تعيش سنوات بعد زوال أسبابها.

ميزة JVM

تحسينات اللغة مهمة، لكن أعمق ميزة لجافا تبقى الـ JVM. بعد ثلاثة عقود من التحسين، يُعد HotSpot JVM من أكثر بيئات التشغيل تطوراً التي بُنيت على الإطلاق.

  • تجميع JIT. تحلل JVM الكود الجاري تنفيذه وتجمّع الدوال الساخنة إلى كود آلي محسّن. في التطبيقات طويلة التشغيل (الخوادم ومعالجة البيانات) غالباً ما يضاهي أداء جافا أو يتفوق على C++ لأن JIT يستطيع التحسين وفق سلوك التشغيل الفعلي، لا التحليل الساكن فقط.
  • جمع القمامة. تقدم خوارزميات GC الحديثة (ZGC وShenandoah) أزمنة توقف أقل من الميلي ثانية حتى مع أكوام تصل إلى تيرابايت. انتقاد «توقفات GC تقتل زمن الاستجابة» لم يعد صحيحاً منذ سنوات، فهذه المجمعات تعمل بالتوازي مع التطبيق.
  • المراقبة. يوفر JFR (Java Flight Recorder) تحليلاً آمناً للإنتاج بتكلفة شبه معدومة. يمكنك قياس استخدام المعالج وتخصيص الذاكرة وتنافس الأقفال وزمن الإدخال والإخراج وسلوك GC دون إبطاء التطبيق.
  • نضج المنظومة. يحتوي Maven Central على ملايين الحزم. أدوات البناء (Gradle وMaven) مفهومة جيداً. منظومة الاختبار (JUnit وMockito وTestcontainers) ممتازة. وقصة النشر (الحاويات وGraalVM native images) نضجت بشكل ملحوظ.

GraalVM وNative Images

أكبر نقاط ضعف جافا كانت دائماً زمن البدء. تحتاج JVM إلى مئات الميلي ثانية للتهيئة وتحميل الفئات وتسخين مترجم JIT. بالنسبة للدوال بلا خوادم وأدوات سطر الأوامر، هذا العبء غير مقبول.

يعالج GraalVM Native Image هذا بتجميع تطبيقات جافا مسبقاً (ahead-of-time) إلى ملفات تنفيذية مستقلة. لا حاجة إلى JVM. ينخفض زمن البدء من مئات الميلي ثانية إلى خانة الآحاد بالميلي ثانية. وتنخفض الذاكرة لأنه لا يوجد مفسر ولا مترجم JIT ولا بيانات وصفية للفئات تُحمّل.

المقايضة: الصور الأصلية تفقد التحسين التكيفي الذي تقدمه JVM. التطبيق المترجَم بـ JIT يصبح أسرع مع الوقت مع تعلم JVM للمسارات الساخنة، أما الصورة الأصلية فتبدأ سريعة ولا تتحسن بعد ذلك. بالنسبة للعمليات قصيرة العمر (أدوات سطر الأوامر والدوال بلا خوادم) تفوز الصور الأصلية. أما للخوادم طويلة التشغيل فإن JIT في JVM ينتج في النهاية كوداً أسرع. اختر الأداة المناسبة لخصائص بيئة التشغيل لديك.

جافا الحديثة مقابل البدائل

اللغات التي «حلّت محل» جافا — Go وKotlin وRust — ممتازة. لكن جافا الحديثة تنافس بفعالية أكبر مما يدرك الناس.

Go بساطتها جذابة، لكن جافا تملك الآن virtual threads (تعادل goroutines) ونظام أنواع أغنى بكثير. أنظمة الأنواع مهمة للقواعد البرمجية الكبيرة، ونظام جافا — خصوصاً مع sealed types وpattern matching — يلتقط أخطاء لا يلتقطها نظام الواجهات في Go.

Kotlin تحسّن صياغة جافا لكنها تعمل على نفس JVM. معظم مزايا Kotlin على Java 8 (أمان القيم الفارغة، وdata classes، وcoroutines) لها مكافئات جزئية أو كاملة في جافا الحديثة (أنماط Optional، وRecords، وVirtual threads). Kotlin لا تزال أكثر إيجازاً، لكن الفجوة تقلصت بشكل كبير.

Rust تشغل مساحة مختلفة — برمجة الأنظمة بدون جامع قمامة. لا ينبغي لجافا أن تنافس هناك. لكن في تطبيقات الخوادم ومعالجة البيانات والبرمجيات المؤسسية، يصعب التغلب على مزيج جافا من الأداء والأمان ونضج المنظومة.

دورة الإصدارات كل ستة أشهر هي الابتكار الحقيقي

أكثر من أي ميزة منفردة، غيّرت دورة الإصدار كل ستة أشهر مسار جافا. قبل 2017، كانت إصدارات جافا أحداثاً تستغرق ثلاث إلى أربع سنوات تحاول شحن كل شيء دفعة واحدة. تتأخر الميزات لأنها غير جاهزة، فيتأخر الإصدار كله، ويتولد ضغط لشحن كل شيء في الإصدار التالي، فيتأخر ذلك أيضاً. استغرق Java 9 أكثر من ثلاث سنوات، جزئياً بسبب تعقيد نظام الوحدات (module system).

مع إصدارات كل ستة أشهر، تُشحن الميزات حين تكون جاهزة. تطورت pattern matching تدريجياً عبر Java 16 حتى 24، وأضاف كل إصدار جزءاً منها. مرت virtual threads بمرحلتي معاينة (preview) قبل الإصدار النهائي. يتيح هذا النهج التدريجي لفريق جافا جمع ملاحظات من الواقع وتعديل التصاميم قبل الالتزام بقرارات API دائمة.

الدرس يتجاوز جافا: إصدارات صغيرة ومتكررة تتراكم لتصنع تغييراً جذرياً. كل إصدار من جافا منذ 17 كان متواضعاً بحد ذاته. مجتمعةً، أعادت اختراع اللغة. إذا جربت جافا قبل خمس سنوات وانصرفت بسبب الإسهاب، فجرّبها مرة أخرى. قد تتفاجأ بما ستجده.