JavaRush /Blog Java /Random-MS /Akhir, Pemalar dan Kekal di Jawa

Akhir, Pemalar dan Kekal di Jawa

Diterbitkan dalam kumpulan
hello! Perkataan "pengubah suai" sudah biasa kepada anda. Sekurang-kurangnya, anda telah menemui pengubah suai akses (awam, peribadi) dan pengubah suai statik. Hari ini kita akan bercakap tentang pengubah suai akhir khas . Ia boleh dikatakan "mengukuhkan" kawasan program kami di mana kami memerlukan tingkah laku yang berterusan, tidak jelas dan tidak berubah. Ia boleh digunakan dalam tiga bidang program kami: kelas, kaedah dan pembolehubah. Kekal dalam Java: akhir, pemalar dan Kekal - 2 Mari kita lalui mereka satu persatu. Jika pengisytiharan kelas mengandungi pengubah suai akhir , ini bermakna anda tidak boleh mewarisi daripada kelas ini. Dalam kuliah sebelumnya, kami melihat contoh mudah warisan: kami mempunyai kelas ibu bapa Animaldan dua kelas kanak-kanak - CatdanDog
public class Animal {
}

public class Cat extends Animal {
   //..поля и методы класса Cat
}

public class Dog extends Animal {

   //..поля и методы класса Dog
}
Walau bagaimanapun, jika kita menentukan Animalpengubah suai untuk kelas, kelas juga finaltidak akan dapat mewarisi daripadanya . CatDog
public final class Animal {

}

public class Cat extends Animal {

   //ошибка! Cannot inherit from final Animal
}
Pengkompil serta-merta menghasilkan ralat. Terdapat banyak -class telah dilaksanakan di Java final. Yang paling terkenal daripada mereka yang sentiasa anda gunakan ialah String. Selain itu, jika kelas diisytiharkan sebagai final, semua kaedahnya juga menjadi final. Apakah maksudnya? Jika pengubah suai ditentukan untuk kaedah final, kaedah ini tidak boleh ditindih. Sebagai contoh, kami mempunyai kelas Animalyang mentakrifkan kaedah voice(). Walau bagaimanapun, anjing dan kucing jelas "bercakap" secara berbeza. Oleh itu, dalam setiap kelas - Catdan Dog- kami akan mencipta kaedah voice(), tetapi kami akan melaksanakannya secara berbeza.
public class Animal {

   public void voice() {
       System.out.println("Voice!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void voice() {
       System.out.println("Woof!");
   }
}
Dalam kelas Catdan Dogkami telah mengatasi kaedah kelas induk. Sekarang haiwan itu akan bersuara bergantung pada objek kelasnya:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();

       cat.voice();
       dog.voice();
   }
}
Kesimpulan: Meow! woof! Walau bagaimanapun, jika Animalkami mengisytiharkan kaedah dalam kelas voice()sebagai final, tidak mungkin untuk mentakrifkannya semula dalam kelas lain:
public class Animal {

   public final void voice() {
       System.out.println("Voice!");
   }
}


public class Cat extends Animal {

   @Override
   public void voice() {//ошибка! final-метод не может быть переопределен!
       System.out.println("Meow!");
   }
}
Kemudian objek kami akan dipaksa untuk menggunakan kaedah voice()seperti yang ditakrifkan dalam kelas induk:
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   cat.voice();
   dog.voice();
}
Kesimpulan: Suara! Suara! Sekarang mengenai final-pembolehubah. Jika tidak, ia dipanggil pemalar . Pertama (dan yang paling penting), nilai pertama yang diberikan kepada pemalar tidak boleh diubah. Ia ditetapkan sekali dan selama-lamanya.
public class Main {

   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;//ошибка! Нельзя присвоить новое meaning final-переменной!
   }
}
Pemalar tidak perlu dimulakan dengan segera. Ini boleh dilakukan kemudian. Tetapi nilai yang diberikan dahulu akan kekal selama-lamanya.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;//так делать можно
}
Kedua, perhatikan nama pembolehubah kami. Pemalar Java mempunyai konvensyen penamaan yang berbeza. Ini bukan camelCase yang biasa kita lakukan. Dalam kes pembolehubah biasa, kami akan memanggilnya constantExample, tetapi nama pemalar ditulis dalam huruf besar, dan di antara perkataan (jika terdapat beberapa daripadanya) terdapat garis bawah - "CONSTANT_EXAMPLE". Mengapa pemalar diperlukan? Sebagai contoh, ia akan berguna jika anda sentiasa menggunakan beberapa nilai tetap dalam program. Katakan anda memutuskan untuk mencatat sejarah dan menulis permainan "The Witcher 4" sahaja. Permainan ini jelas akan sentiasa menggunakan nama watak utama - "Geralt of Rivia". Adalah lebih baik untuk memisahkan baris ini dan nama wira lain menjadi pemalar: nilai yang anda perlukan akan disimpan di satu tempat, dan anda pasti tidak akan tersilap apabila menaipnya untuk kali ke juta.
public class TheWitcher4 {

   private static final String GERALT_NAME = "Геральт из Ривии";
   private static final String YENNEFER_NAME = "Йеннифэр из Венгерберга";
   private static final String TRISS_NAME = "Трисс Меригольд";

   public static void main(String[] args) {

       System.out.println("Ведьмак 4");
       System.out.println("Это уже четвертая часть Ведьмака, а " + GERALT_NAME + " ниHow не определится кто ему" +
               " нравится больше: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("Но если вы никогда не играли в Ведьмака - начнем сначала.");
       System.out.println("Главного героя зовут " + GERALT_NAME);
       System.out.println(GERALT_NAME + " - ведьмак, охотник на чудовищ");
   }
}
Kesimpulan:
Ведьмак 4
Это уже четвертая часть Ведьмака, а Геральт из Ривии ниHow не определится, кто ему нравится больше: Йеннифэр из Венгерберга or Трисс Меригольд.
Но если вы никогда не играли в Ведьмака — начнем сначала.
Главного героя зовут Геральт из Ривии
Геральт из Ривии — ведьмак, охотник на чудовищ
Kami telah memisahkan nama watak kepada pemalar, dan kini kami pasti tidak akan salah mengejanya, dan tidak perlu menulisnya dengan tangan setiap kali. Satu lagi kelebihan: jika kita akhirnya perlu menukar nilai pembolehubah sepanjang keseluruhan program, sudah cukup untuk melakukannya di satu tempat, dan bukannya membuat semula secara manual sepanjang keseluruhan kod :)

Jenis tidak berubah

Semasa anda bekerja di Java, anda mungkin sudah terbiasa dengan fakta bahawa pengaturcara hampir sepenuhnya mengawal keadaan semua objek. Dikehendaki - mencipta objek Cat. Jika saya mahu, saya menamakannya semula. Jika dia mahu, dia mengubah umurnya, atau sesuatu yang lain. Tetapi di Jawa terdapat beberapa jenis data yang mempunyai keadaan istimewa. Mereka tidak boleh berubah , atau Tidak boleh berubah . Ini bermakna jika kelas tidak boleh diubah, keadaan objeknya tidak boleh diubah. Contoh? Anda mungkin terkejut, tetapi contoh kelas Immutable yang paling terkenal ialah String! Nampaknya kita tidak boleh menukar nilai rentetan? Mari kita cuba:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1 = "I love Python";//но поведение str1 ниHow не влияет на str2
   System.out.println(str2);//str2 продолжает указывать на строку "I love Java", хотя str1 уже указывает на другой an object
}
Kesimpulan: Saya suka Java Saya suka Java Selepas kami menulis:
str1 = "I love Python";
objek dengan rentetan "Saya suka Java" tidak berubah dan tidak pergi ke mana-mana. Ia wujud dengan selamat dan mempunyai teks yang sama persis di dalamnya seperti sebelumnya. Kod:
str1 = "I love Python";
baru sahaja mencipta objek lain dan kini pembolehubah str1menunjuk kepadanya. Tetapi kita tidak boleh mempengaruhi objek "Saya suka Java" dalam apa cara sekalipun. Okay, jom cuba cara lain! Kelas ini Stringpenuh dengan kaedah, dan sebahagian daripadanya nampaknya mengubah keadaan baris! Sebagai contoh, terdapat kaedah replace(). Mari tukar perkataan “Java” kepada perkataan “Python” dalam baris kami!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.replace("Java", "Python");//попробуем изменить состояние str1, заменив слово "Java" на “Python”
   System.out.println(str2);
}
Kesimpulan: Saya suka Java Saya suka Java Ia tidak berjaya lagi! Mungkin kaedah lengkung tidak berfungsi? Jom cuba yang lain. Sebagai contoh, substring(). Memangkas rentetan berdasarkan nombor aksara yang dihantar. Mari kita kurangkan kita kepada 10 aksara pertama:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.substring(10);//обрезаем исходную строку
   System.out.println(str2);
}
Kesimpulan: Saya suka Java Saya suka Java Kekal dalam Java: akhir, pemalar dan Kekal - 3 Tiada apa-apa yang berubah. Dan ia tidak sepatutnya. Seperti yang kami katakan, objek Stringtidak boleh berubah. Apakah semua kaedah kelas ini String? Mereka boleh memangkas garisan, menukar aksara di dalamnya, dsb. Mengapa mereka diperlukan jika tiada apa yang berlaku? Mereka boleh! Tetapi mereka mengembalikan objek rentetan baharu setiap kali. Tidak ada gunanya menulis:
str1.replace("Java", "Python");
- anda tidak akan menukar objek asal. Tetapi jika anda menulis hasil kaedah ke dalam pembolehubah rujukan baharu, anda akan segera melihat perbezaannya!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   String str1AfterReplacement =  str1.replace("Java", "Python");
   System.out.println(str2);

   System.out.println(str1AfterReplacement);
}
Ini adalah satu-satunya cara semua kaedah ini Stringberfungsi. Anda tidak boleh melakukan apa-apa dengan objek "Saya suka Java" . Hanya buat objek baharu dan tulis: "Objek baharu = hasil daripada beberapa manipulasi dengan objek "Saya suka Java" ." Apakah jenis lain yang tidak boleh diubah? Daripada apa yang anda pasti perlu ingat sekarang - semua kelas pembalut berbanding jenis primitif tidak boleh diubah. Integer, Byte, Character, Short, Boolean, Long, Double, Float- semua kelas ini mencipta objek Tidak boleh ubah . Ini juga termasuk kelas yang digunakan untuk mencipta nombor besar - BigIntegerdan BigDecimal. Kami baru-baru ini melalui pengecualian dan menyentuh StackTrace. Jadi: objek kelas java.lang.StackTraceElement juga tidak boleh diubah. Ini adalah logik: jika seseorang boleh menukar data pada timbunan kami, ia boleh menafikan semua kerja dengannya. Bayangkan seseorang masuk ke StackTrace dan menukar OutOfMemoryError kepada FileNotFoundException . Dan anda harus bekerja dengan timbunan ini dan mencari punca ralat. Dan program ini tidak menggunakan fail sama sekali :) Oleh itu, untuk berada di bahagian yang selamat, objek ini tidak boleh diubah. Nah, dengan StackTraceElement ia lebih kurang jelas. Mengapa sesiapa mahu membuat rentetan tidak berubah? Apakah masalahnya jika boleh mengubah nilai mereka. Ia mungkin akan menjadi lebih mudah :/ Terdapat beberapa sebab untuk ini. Pertama, menjimatkan memori. Rentetan tidak berubah boleh diletakkan String Pooldan yang sama boleh digunakan setiap kali dan bukannya mencipta yang baharu. Kedua, keselamatan. Sebagai contoh, kebanyakan log masuk dan kata laluan dalam mana-mana program adalah rentetan. Kemungkinan menukarnya boleh membawa kepada masalah dengan kebenaran. Terdapat sebab lain, tetapi kami belum memahaminya lagi dalam mempelajari Java—kami akan kembali kemudian.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION