جافا 10 هو أسرع إصدار لإصدار جافا في تاريخها البالغ 23 عامًا. تعرضت جافا لانتقادات بسبب نموها وتطورها البطيء، ولكن جافا 10 كسرت تلك المفهوم. جافا 10 هو إصدار يحمل العديد من التغييرات المستقبلية، والتي قد لا تكون نطاقها وتأثيرها واضحة ولكنها بعيدة المدى. في هذا المقال، سنناقش مختلف الميزات التي تمت إضافتها في إصدار جافا 10. قبل ذلك، دعونا نلقي نظرة على بعض التغييرات التي تم إدخالها على نموذج إصدار جافا.
نموذج الدعم على المدى الطويل
بدءًا من عام 2017، أعلنت Oracle ومجتمع Java تحولها إلى وتيرة جديدة تبلغ 6 أشهر لجافا. انتقلت إلى نموذج الدعم على المدى الطويل (LTS) لمنتجات Oracle Java SE. ماذا يعني هذا؟ ستقدم الإصدارات LTS للمنتجات دعمًا رئيسيًا ومستدامًا من Oracle وسيتم استهدافها كل 3 سنوات. يتم نمذجة كل إصدار جافا بناءً على ميزة رئيسية واحدة أو اثنتين، وتلك الميزات تدفع بالإصدار. أي عقبة تؤجل الإصدار ويتأخر في السوق. كان مشروع Jigsaw ميزة رئيسية في جافا 9، حيث أرجأ تواريخ الإصدار عدة مرات وتأخر الإصدار لأكثر من 1.5 عام. سيتبع إصدار وتيرة 6 أشهر قطار إصدار. سيكون لدى قطار الإصدار جدول زمني كل 6 أشهر. الميزات التي تجتاز تضمينها على القطار؛ وإلا فإنها تنتظر القطار المجدول التالي.
Oracle JDK vs Open JDK
لاجعلها أكثر ودودة للمطورين، تعزز مجتمع أوراكل وجافا الآن البيانات التنفيذية لـ OpenJDK كـ JDK الأساسي المتقدم. هذا يعتبر إرتاحة كبيرة مقارنة بالأيام السابقة، حيث كانت بيانات التنفيذية لـ JDK خاصة الملكية ومرخصة من قبل أوراكل، مما كان يحمل العديد من القيود حول إعادة التوزيع. ستواصل أوراكل إنتاج JDK الخاصة بها، ولكن فقط لإصدارات الدعم على المدى الطويل. هذه خطوة نحو جعلها أكثر ودية للسحابة والحاويات، حيث يمكن توزيع بيانات التنفيذية المفتوحة المصدر كجزء من حاوية. ماذا يعني هذا؟ سيتم إصدار بيانات التنفيذية لـ Open JDK كل 6 أشهر، بينما سيتم إصدار بيانات التنفيذية لـ Oracle JDK كل 3 سنوات (الإصدار LTS). أي بيانات تنفيذية JDK ستتبنى؟ تستغرق المؤسسات الكبيرة وقتًا للانتقال بين الإصدارات؛ فهي تتمسك بالإصدار حتى تستطيع التحرك. كان تبني الصناعة لـ Java 6 أكثر من Java 7 ومن ثم الصناعة تتحرك تدريجياً إلى Java 8. في رأيي، ستكون الإصدارات LTS هي الأكثر تفضيلًا من قبل الشركات. ومع ذلك، ما إذا كانت ستكون الإصدارات LTS لـ Oracle JDK أو Open JDK هو أمر لا يزال غير معروف، جزئيًا لأن هناك الكثير يحدث في مجال السحابة. Java 9 و 10 هما إصدارات غير LTS. سيكون Java 11 الذي سيصدر في سبتمبر 2018 إصدارًا LTS.
ميزات جافا 10
لنلق نظرة سريعة على الميزات المتاحة في جافا 10.
باعتماد دورة الإصدار الزمنية، قامت أوراكل بتغيير مخطط سلسلة الإصدارات لمنصة Java SE و JDK، والمعلومات المتعلقة بالإصدار، لنماذج الإصدار الزمني الحالية والمستقبلية. النمط الجديد لرقم الإصدار هو: `$FEATURE.$INTERIM.$UPDATE.$PATCH` $FEATURE: سيتم زيادة العداد كل 6 أشهر وسيعتمد على إصدارات الإصدار المميزة، على سبيل المثال: JDK 10، JDK 11. $INTERIM: سيتم زيادة العداد للإصدارات غير المميزة التي تحتوي على إصلاحات الأخطاء المتوافقة والتحسينات ولكن لا تحتوي على تغييرات غير متوافقة. عادةً ما سيكون هذا العداد صفرًا، حيث لن يكون هناك إصدار مؤقت في فترة ستة أشهر. تم الاحتفاظ بهذا لمراجعة مستقبلية لنموذج الإصدار. $UPDATE: سيتم زيادة العداد للإصدارات التحديثية المتوافقة التي تصحح مشاكل الأمان والانحدار والأخطاء في الميزات الجديدة. يتم تحديث هذا العداد بعد شهر واحد من إصدار الميزة وكل 3 أشهر بعد ذلك. يعتبر إصدار أبريل 2018 هو JDK 10.0.1، والإصدار لشهر يوليو هو JDK 10.0.2، وهكذا $PATCH: سيتم زيادة العداد لإصدار طارئ لإصلاح مشكلة حرجة. تمت إضافة واجهات برمجية جديدة للحصول على قيم هذه العدادات برمجياً. دعنا نلقي نظرة؛
Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();
الآن، دعونا نلقي نظرة على مشغل Java الذي يُرجع معلومات الإصدار:
$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
صيغة رقم الإصدار هي “10” لأنه لا يوجد عداد آخر غير الصفر. تمت إضافة تاريخ الإصدار. يمكن قراءة 18.3 على أنه العام 2018 والشهر الثالث، بناء 10+46 هو البناء 46 للإصدار 10. لبناء تخيلي 93 من JDK 10.0.1، سيكون البناء هو 10.0.1+939. ### استنتاج نوع المتغير المحلي (JEP 286)
التصريح المحلي للتعرف على نوع المتغيرات هو أكبر ميزة جديدة في جافا 10 للمطورين. يضيف التصريح المحلي للتعرف على النوع إلى التصريحات بالمتغيرات المحلية مع المبادئ. يمكن استخدام التعرف المحلي على النوع فقط في السيناريوهات التالية:
- محدودة فقط إلى المتغير المحلي مع المبادئ
- فهرس لحلقة التكرار المحسنة أو الفهارس
- محلي معلن في حلقة التكرار
دعونا نلقي نظرة على استخدامه:
var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList
// فهرس حلقة التكرار المحسنة
for (var number : numbers) {
System.out.println(number);
}
// متغير محلي معلن في حلقة
for (var i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
يمكنك قراءة المزيد عنه في مقالنا الحصري على تعرف على نوع المتغيرات المحلية في جافا 10. 13. ### محاكي JIT مبني على جافا التجريبي (JEP 317)
هذه الميزة تمكن مترجم جافا المبني على Graal JIT من استخدامه كمترجم JIT تجريبي على منصة Linux/x64. هذا بعيدًا عن الأضافات الأكثر تطورًا في قائمة ميزات جافا 10. تم تقديم Graal في جافا 9. إنه بديل لمترجم JIT الذي اعتدنا عليه. إنه إضافة إلى JVM، مما يعني أن مترجم JIT ليس مرتبطًا بـ JVM ويمكن توصيله واستبداله بأي إضافة أخرى تتوافق مع واجهة JVMCI (Java-Level JVM Compiler Interface). كما يقدم أيضًا ترجمة مسبقة (AOT) في عالم جافا. كما يدعم تفسير اللغات متعددة اللغات. “مترجم JIT مبني على جافا مكتوب بلغة جافا لتحويل بايت كود جافا إلى رمز آلي.” هل هذا محير؟ إذا كانت JVM مكتوبة بلغة جافا، فهل لا تحتاج إلى JVM لتشغيل JVM؟ يمكن ترجمة JVM AOT ومن ثم يمكن استخدام مترجم JIT داخل JVM لتحسين الأداء من خلال تحسين الرمز الحي. Graal هو إعادة كتابة كاملة لمترجم JIT في جافا من البداية. كان المترجم JIT السابق مكتوبًا بـ c++. يُعتبر واحدًا من المراحل النهائية في تطور أي لغة برمجة. يمكنك التبديل إلى Graal باستخدام المعلمات التالية لـ jvm:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
يمكنك معرفة المزيد عن Graal من عرض Chris Seaton.
تساعد هذه الميزة في تحسين بداية تشغيل التطبيق، وتمتد الميزة القائمة لمشاركة بيانات الفئة (“CDS”) للسماح بوضع فئات التطبيق في الأرشيف المشترك. JVM عند بدء التشغيل يقوم ببعض الخطوات الأولية، واحدة منها هي تحميل الفئات في الذاكرة. إذا كان هناك عدة ملفات jar تحتوي على فئات متعددة، فإن التأخير في الطلب الأول واضح بشكل واضح. هذا يصبح مشكلة مع هندسة بدون خادم، حيث أن وقت البدء حرج. من أجل تقليل وقت بدء تشغيل التطبيق، يمكن استخدام مشاركة بيانات فئة التطبيق. الفكرة هي تقليل البصمة عن طريق مشاركة بيانات فئة مشتركة عبر عمليات Java المختلفة. يمكن تحقيق ذلك بالخطوات الـ 3 التالية: تحديد الفئات للأرشفة: استخدم مشغل java لإنشاء قائمة بالملفات للأرشفة، يمكن تحقيق ذلك بالمعاملات التالية:
$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld
إنشاء أرشيف AppCDS: استخدم مشغل java لإنشاء أرشيف قائمة الملفات المستخدمة لـ Application CDS، يمكن تحقيق ذلك بالمعاملات التالية:
$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
استخدام أرشيف AppCDS: استخدم مشغل Java بالمعاملات التالية لاستخدام Application CDS.
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
جعل G1 مجمع القمامة الافتراضي في JDK 9. يتجنب G1 Garbage collector أي جمع كامل للقمامة، ولكن عندما لا تتمكن الخيوط المتزامنة للجمع من إحياء الذاكرة بسرعة كافية، يتأثر تجربة المستخدم. يعزز هذا التغيير سرعة استجابة G1 في أسوأ الحالات من خلال جعل GC الكامل متوازيًا. تم توازي ألگوريتم العلامة-التنظيف-الضغط من مجمع G1 كجزء من هذا التغيير وسيتم تشغيله عندما لا تتمكن الخيوط المتزامنة للجمع من إحياء الذاكرة بسرعة كافية.
25. ### واجهة جمع القمامة (JEP 304)
هذا التغيير مستقبلي. إنه يعزز عزل الشيفرة لمجمعات القمامة المختلفة من خلال إدخال واجهة مشتركة لجمع القمامة. يوفر هذا التغيير تعددًا أفضل لشيفرة GC الداخلية. سيساعد ذلك في المستقبل في إضافة مجمعات GC جديدة دون تغيير الشيفرة الحالية، كما سيساعد في إزالة أو الاعتناء بمجمع GC السابق.
26. ### توسيعات وسم اللغة اليونيكود الإضافية (JEP 314)
تعزيز java.util.Locale وواجهات API ذات الصلة لتنفيذ توسيعات اللغة BCP 47 اليونيكود الإضافية. اعتبارًا من Java SE 9، تدعم توسيعات وسم اللغة BCP 47 U المعتمدة هي “ca” و “nu”. ستضيف هذه JEP دعمًا لتوسيعات إضافية التالية:
- cu (نوع العملة)
- fw (أول يوم في الأسبوع)
- rg (تجاوز المنطقة)
- tz (وحدة التوقيت)
من أجل دعم هذه الامتدادات الإضافية، تم إجراء تغييرات على مختلف واجهات برمجة التطبيقات لتوفير المعلومات استنادًا إلى U أو الامتدادات الإضافية.
java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider
من أجل تعزيز OpenJDK وجعلها أكثر جاذبية لمستخدمي المجتمع، توفر هذه الميزة مجموعة افتراضية من شهادات هيئة الاعتماد الجذر (CA) في JDK. وهذا يعني أيضًا أن كل من النسخ الثنائية لـ Oracle و Open JDK ستكون وظيفياً متطابقة. ستعمل مكونات الأمان الحيوية مثل TLS بشكل افتراضي في تجميعات OpenJDK المستقبلية.30. ### Thread-Local Handshakes (JEP 312)
هذه ميزة داخلية في JVM لتحسين الأداء. عملية التصافح هي استدعاء يتم تنفيذه لكل JavaThread أثناء وجود تلك الخيط في حالة safepoint. يتم تنفيذ الاستدعاء إما بواسطة الخيط نفسه أو بواسطة خيط VM مع الاحتفاظ بالخيط في حالة محظورة. توفر هذه الميزة وسيلة لتنفيذ استدعاء على الخيوط دون إجراء safepoint عام في VM. تجعل من الممكن ورخيصة التوقف عن الخيوط الفردية وليس فقط جميع الخيوط أو لا شيء.31. ### Heap Allocation on Alternative Memory Devices (JEP 316)
تطبيقات أصبحت تتطلب ذاكرة أكبر، هناك زيادة في تطبيقات السحابة الأصلية، وقواعد البيانات في الذاكرة، وتطبيقات البث. من أجل تلبية هذه الخدمات، هناك مجموعة متنوعة من الهياكل الذاكرية المتاحة. تعزز هذه الميزة قدرة HotSpot VM على تخصيص كومة الكائنات في جافا على جهاز ذاكرة بديل، مثل NV-DIMM، كما يحدده المستخدم. تستهدف هذه JEP أجهزة الذاكرة البديلة التي تتمتع بنفس الدلالات مثل DRAM، بما في ذلك دلالات العمليات الذرية، ويمكن استخدامها بدلاً من DRAM لكومة الكائنات دون أي تغيير في رمز التطبيق الموجود.
### إزالة أداة إنشاء رأس Native-Header – javah (JEP 313)
هذا تغيير للصيانة لإزالة أداة javah من JDK. تمت إضافة وظيفة الأداة في `javac` كجزء من JDK 8، مما يوفر القدرة على كتابة ملفات رأس Native في وقت الترجمة، مما يجعل javah غير مفيدة.
### توحيد غابة JDK في مستودع واحد (JEP 296)
على مر السنين، كانت هناك مستودعات متعددة في Mercurial لشيفرة JDK. توفر المستودعات المختلفة بعض المزايا، لكنها كانت تعاني أيضًا من عدة مشاكل تشغيلية. كجزء من هذا التغيير، تم دمج العديد من مستودعات غابة JDK في مستودع واحد من أجل تبسيط وتسريع التطوير.
### تغييرات واجهة التطبيق البرمجي
أضاف Java 10 وحذف (نعم، ليس خطأ إملائيًا) العديد من واجهات البرمجة (API). قدمت Java 9 تحسينات في التشويه حيث تم وضع علامات على بعض واجهات البرمجة لتكون قيد الإزالة في الإصدارات المستقبلية. الواجهات التي تمت إزالتها: يمكنك العثور على الواجهات التي تمت إزالتها هنا. الواجهات التي تمت إضافتها: تمت إضافة 73 واجهة برمجة جديدة في Java 10. يمكنك العثور على الواجهات التي تمت إضافتها مع المقارنة هنا. دعونا نستعرض بعض الإضافات:
- تمت إضافة واجهات List و Map و Set مع طريقة copyOf(Collection) ثابتة. تُرجع قائمة ، خريطة أو مجموعة لا يمكن تعديلها تحتوي على الإدخالات المقدمة. بالنسبة لقائمة ، إذا تم تعديل القائمة المعطاة لاحقًا ، فإن القائمة المرجعية لن تعكس مثل هذه التعديلات.
- Optional وتفرعاتها الرئيسية تحصل على طريقة orElseThrow(). هذا هو بالضبط نفس get() ، ومع ذلك ، تشير وثيقة Java إلى أنها بديل مفضل عن get().
- تحصل فئة Collectors على طرق متنوعة لجمع مجموعات لا يمكن تعديلها (مجموعة ، قائمة ، خريطة)
List actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// تمت إضافة واجهة برمجة جديدة - تنشئ قائمة لا يمكن تعديلها من قائمة.
List copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// ستؤدي copyOfActors.add("Robert De Niro"); إلى إثارة
// UnsupportedOperationException
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
String str = "";
Optional name = Optional.ofNullable(str);
// تمت إضافة واجهة برمجة جديدة - تعتبر الخيار المفضل بالنسبة إلى طريقة get()
name.orElseThrow(); // same as name.get()
// تمت إضافة واجهة برمجة جديدة - Collectors.toUnmodifiableList
List collect = actors.stream().collect(Collectors.toUnmodifiableList());
// ستؤدي collect.add("Tom Hanks"); // إلى إثارة
// UnsupportedOperationException
الختام
في هذا المقال، قمنا بمراجعة إضافة الميزات الجديدة المختلفة في Java 10. إذا كنت تعتقد أن هناك أي شيء مهم تم تفويته هنا، يرجى إعلامنا من خلال التعليقات. كالعادة، يمكنك التحقق من الشيفرة الكاملة على GitHub هنا.
Source:
https://www.digitalocean.com/community/tutorials/java-10-features