انشاء التلاعب النهائي المتغير في Java




الوراثة في الجافا (8)

يمكنك استدعاء أي طريقة عليه حتى إذا كانت الطريقة يمكن أن تغير حالة الكائن الذي يشير إليه المرجع. على سبيل المثال

final MyClass myClass = new MyClass();
myClass.setVar(something);

هذا أمر جيد لأن myClass نفسها لا تتغير ، أي أنك لا تفعل myClass = myClass1; .

هل يمكن لأي أحد أن يخبرني ما هو معنى السطر التالي في سياق Java:

لا يزال من الممكن التلاعب بالتغيير النهائي ما لم يكن ثابتًا

بقدر ما أعرف ، من خلال إعلان أي متغير كنهائي ، لا يمكنك تغييره مرة أخرى ، فماذا تعني بكلمة غير قابلة للتغيير في السطر أعلاه؟


Answer #1

لا يمكنك تغيير أي كائن أو قيمة يشير إليها المتغير الأخير. يمكنك فقط تعيين متغير نهائي مرة واحدة.

هذا ليس له أي تأثير على ما إذا كان يمكنك تغيير حالة الكائن. لا يزال من الممكن التلاعب بالشيء نفسه ما لم يتم تشفيره بطريقة تمنع هذا التلاعب. الكائن غير القابل للتغيير هو كائن لا يمكن تغيير حالته.


Answer #2

إذا كان لديك مرجع نهائي إلى كائن Java ، فلا يزال بإمكانك التعامل معه ولكن لا يمكنك تغيير مرجعه. على سبيل المثال ، يعد هذا الرمز قانونيًا تمامًا:

import javax.swing.JLabel;

class Test1 {
    private final static JLabel l = new JLabel("Old text");
    public static void main(String[] args) {
        System.err.println(l.getText());
        l.setText("New Text");
        System.err.println(l.getText());
    }
}

لكن لا يمكنك قول:

l = new JLabel("Newest Text");

بعد المهمة الأولى ل ل. لاحظ أنه يمكنك القيام بذلك على الرغم من:

import javax.swing.JLabel;

class Test1 {
    public static void main(String[] args) {
        final JLabel l;
        String s = getArbitaryString(); // Assume this method returns a string
        l = new JLabel(s);
        System.err.println(l.getText());
    }
}

يمكن القيام بذلك لأنه عندما يتم الإعلان عن عدم تخصيص أي شيء ولا حتى لاغية. لذا يُسمح لك بتعيين شيء له مرة واحدة فقط.

نفس الشيء ينطبق على الأوليات. يمكنك تعيين قيمة له على النحو التالي:

class Test1 {
    public static void main(String[] args) {
        final int i;
        i = 2;
    }
}

ولكن الآن لا يمكنك التلاعب بها لأن الشيء الوحيد الذي يمكنك القيام به للأنواع البدائية هو تعيين قيم لها.


Answer #3

هذا يعني أنه إذا كان المتغير النهائي هو نوع مرجع (أي ليس بديلاً مثل int) ، فهو المرجع الوحيد الذي لا يمكن تغييره. لا يمكن جعله يشير إلى كائن مختلف ، ولكن يمكن تغيير حقول الكائن الذي يشير إليه ، إذا سمحت الطبقة بذلك. فمثلا:

final StringBuffer s = new StringBuffer();

لا يزال من الممكن تغيير محتوى StringBuffer تعسفاً:

s.append("something");

لكن لا يمكنك قول:

s = null;

أو

s = anotherBuffer;

من ناحية أخرى:

final String s = "";

سلاسل غير قابلة للتغيير - ببساطة ليس هناك أي طريقة من شأنها أن تمكنك من تغيير سلسلة (إلا إذا كنت تستخدم انعكاس - والذهاب إلى الجحيم).


Answer #4

كما قال الآخرون ، فهذا يعني أنه يمكنك التعامل مع الكائن الذي يشير إليه المتغير ، لكن لا يمكنك تغيير المرجع (أي تعيين كائن آخر للمتغير).

يمكن تغيير الكائنات القابلة للتغير حسب التصميم ، مثل List (يمكنك إضافة عناصر إليها) في حين إذا كان لديك كائن غير قابل للتغيير مثل String أو Integer لن تتمكن من تغييره (جميع العمليات في الفصل تدعم String إرجاع نسخة جديدة ، ولا تقم بتعديل الكائن الفعلي).


Answer #5

يمكنك التعامل مع المتغيرات النهائية القابلة للتغيير على سبيل المثال من النوع StringBuffer ولكن لا يمكنك التلاعب بالمتغيرات النهائية للأنواع الثابتة.

في حالة المتغيرات القابلة للتغيير ، لا يتم إنشاء كائن جديد في كل مرة يتم فيها تغيير القيمة. ولكن في حالة الأنواع غير القابلة للتغيير ، كلما تم تغيير القيمة ، يتم إنشاء كائن جديد ، لذلك عندما تجعله نهائيًا ، لا يمكنك تعديله.


Answer #6

نعم ، يمكن تعديل المتغير النهائي.

    final StringBuffer s = new StringBuffer();
    // won't work
    s = new StringBuffer();
    //this works
    s.append("hai");

لا يمكنك تغيير المرجع ولكن يمكن تعديل حقول الكائن. لمزيد من التفاصيل


Answer #7

الشخص الذي يقتلني دائما؟

إذا كنت تريد أن تكون المتغيرات النهائية آمنة تمامًا كما كنت تعتقد ، فستحتاج إلى الكثير من الشفرات الإضافية لإرجاع نسخة من سلسلة [].





final