
ينقسم استخدام الكلمة المفتاحية final في الجافا إلى الأقسام التالية
الحقل final
يمكن استخدام الكلمة final قبل اسم عضو بياني وهنا نلاحظ حالتين:
الحقل final من نمط أساسي (primitive)
إذا كان نمط بيانات الحقل هو أحد الأنماط الأساسية (int، float، charوغيرها…) وتم استخدام الكلمة final فهذا يعني أن قيمة هذا الحقل ثابتة لا يسمح بتغيرها ويجب إعطاء هذا الحقل قيمة عند التصريح عنه مباشرة أو ضمن الباني.
مثال:
public class A {
final int y;
// or final int y = 0;
public A() {
y = 0;
// y++; error
}
}
في هذا المثال تم تعريف الحقل y من نمط عدد صحيح وتم إعطاؤه قيمة ضمن الباني وبعدها لم يعد ممكناً تغيير القيمة أبداً وأي محاولة لتغير القيمة ستؤدي إلى ظهور رسالة خطأ.
الحقل من نمط مرجع (كائن من صف ما)
إذا كان لدينا حقل من نمط مرجع مثلاً (Date، Calender، File أو غيرها…) وتم استخدام الكلمة المفتاحية final فهذا يعني أنه لا يمكن تغيير المرجع الخاص بهذا الحقل أبداً ويجب تهيئته لمرة واحدة عند التصريح عنه أو ضمن الباني باستخدام الكلمة new، وبعدها يصبح ممنوعاً إعادة تهيئة هذا الحقل (استخدام new مرة أخرى). لتوضيح هذه الفكرة راقب المثال التالي:
final File file = new File("file.txt");
public A() {
y = 0;
//y++; error
file.setLastModified(10);
file.setReadable(true);
//file=new File("file.txt"); error
}
تم التصريح عن الحقل file من نمط File وتمت تهيئته باستخدام الكلمة new عند التصريح مباشرة، داخل الباني تمكنا من تغيير حالة هذا الحقل باستخدام الدوال setLastModified وsetReadable لكن لو حاولنا إعادة تهيئة هذا الحقل باستخدام الكلمة new سنواجه رسالة خطأ.
الدالة final
هي دالة موجودة في صف أب لا يمكن للأبناء (إن وجدو) أن يقوموا بإعادة كتابة هذه الدالة (override).
مثال
public class A {
final int y;
// or final int y = 0;
final File file = new File("file.txt");
public A() {
y = 0;
// y++; error
file.setLastModified(10);
file.setReadable(true);
// file=new File("file.txt"); error
}
public void m() {
System.out.println("A.m()");
}
}
class B extends A {
@Override
public void m() {
System.out.println("B.m()");
}
}
يمثل الكود السابق الحالة العادية بدون استخدام الكلمة المفتاحية final مع الدالة m لكن بعد استخدام الكلمة المفتاحية final تصبح الدالة غير قابلة لإعادة الكتابة وأي محاولة لإعادة كتابتها تؤدي لظهور رسالة خطأ.
public final void m() {
System.out.println("A.m()");
}
}
class B extends A {
// @Override
// public void m() {
// System.out.println("B.m()");
// } error
}
الصف final
تستخدم final قبل اسم الصف لمنع الصفوف الأخرى من وراثته، ففي المثال السابق لو قمنا باستخدام final مع الصف A لن يتمكن الصف B من وراثة الصف A أبداً.
public final class A {
final int y;
// or final int y = 0;
final File file = new File("file.txt");
public A() {
y = 0;
// y++; error
file.setLastModified(10);
file.setReadable(true);
// file=new File("file.txt"); error
}
public final void m() {
System.out.println("A.m()");
}
}
// class B extends A { error
//
//// @Override
//// public void m() {
//// System.out.println("B.m()");
//// } error
// }