JavaRush /Blog Java /Random-MS /Jadi muktamad...

Jadi muktamad...

Diterbitkan dalam kumpulan
Terdapat kata kunci dalam java - final. Ia boleh digunakan pada kelas, kaedah, pembolehubah (termasuk argumen kaedah). Jadi muktamad... - 1Untuk kelas, ini bermakna kelas tidak boleh mempunyai subkelas, i.e. Harta pusaka adalah dilarang. Ini berguna apabila mencipta immutableobjek (tidak berubah), contohnya kelas Stringyang diisytiharkan sebagai final.
public final class String{
}

class SubString extends String{ //Compilation error
}
Perlu diingatkan juga bahawa pengubah tidak boleh digunakan pada kelas abstrak (dengan kata kunci abstract), finalkerana ini adalah konsep yang saling eksklusif. Untuk kaedah finalbermakna ia tidak boleh ditindih dalam subkelas. Ini berguna apabila kita mahu pelaksanaan asal tidak ditindih.
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Compilation error
        System.out.println("MyReport");
    }
}
Untuk pembolehubah jenis primitif, ini bermakna apabila ditetapkan, nilai tidak boleh diubah. Untuk pembolehubah rujukan, ini bermakna apabila objek ditetapkan, rujukan kepada objek itu tidak boleh diubah. Ia penting! Pautan tidak boleh diubah, tetapi keadaan objek boleh diubah. Dengan java 8 konsep itu muncul - effectively final. Ia hanya terpakai kepada pembolehubah (termasuk argumen kaedah). Intinya ialah walaupun ketiadaan kata kunci yang jelas final, nilai pembolehubah tidak berubah selepas permulaan. Dengan kata lain, anda boleh menggantikan perkataan untuk pembolehubah sedemikian finaltanpa ralat penyusunan. effectively finalPembolehubah boleh digunakan di dalam kelas tempatan ( Local Inner Classes), kelas tanpa nama ( Anonymous Inner Classes), strim (API Strim).
public void someMethod(){
    // In the example below, both a and b are effectively final, since the values ​​are set once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final because value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Compilation error
}
Sekarang mari kita temuduga sedikit. Lagipun, matlamat mengambil kursus JavaRush adalah untuk menjadi pembangun Java dan mendapatkan pekerjaan yang menarik dan bergaji tinggi. Jadi, mari kita mulakan.
  1. Apa yang anda boleh katakan tentang tatasusunan apabila ia diisytiharkan final?

  2. Adalah diketahui bahawa kelas Stringadalah immutable, kelas diisytiharkan final, nilai rentetan disimpan dalam tatasusunan char, yang ditandakan dengan kata kunci final.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
Adakah mungkin untuk menggantikan nilai objek String(tanpa mengubah rujukan kepada objek)? Ini adalah soalan wawancara sebenar. Dan seperti yang ditunjukkan oleh latihan, ramai yang menjawabnya dengan salah. Memahami penggunaan kata kunci final, terutamanya untuk pembolehubah rujukan, adalah sangat penting. Semasa anda berfikir, penyimpangan pantas kepada pasukan JavaRush. Sila tambahkan blok dalam editor teks anda yang membolehkan anda menyembunyikan kandungan, dan apabila anda mengklik padanya, tunjukkan kandungan ini. Jawapan:
  1. Kerana tatasusunan ialah objek, yang finalbermaksud bahawa selepas memberikan rujukan kepada objek, ia tidak lagi boleh diubah, tetapi keadaan objek boleh diubah.

    final int[] array = {1,2,3,4,5};
    array[0] = 9;	//ok, because change the contents of the array - {9,2,3,4,5}
    array = new int[5]; //compile error
  2. Ya awak boleh. Kuncinya ialah memahami penggunaan perkataan berduri finaldengan objek. Menggunakan ReflectionAPI untuk menggantikan nilai.

import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        //Get the value field in the String class
        Field field = value.getClass().getDeclaredField("value");
        //Let's change it
        field.setAccessible(true);
        //Set new value
        field.set(value, "JavaRush".toCharArray());

        System.out.println(value);

        /* Вывод:
         * Old value
         * JavaRush
         */
    }
}
Sila ambil perhatian bahawa jika kami cuba menukar pembolehubah akhir jenis primitif dengan cara ini, tiada apa yang akan berfungsi. Saya cadangkan anda meyakinkan diri anda tentang perkara ini: buat kelas Java, contohnya, dengan final intmedan dan cuba ubah nilainya melalui API Refleksi. Semoga berjaya kepada semua!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION