JavaRush /Java Blog /Random-ID /Final, Konstanta dan Abadi di Java

Final, Konstanta dan Abadi di Java

Dipublikasikan di grup Random-ID
Halo! Kata “pengubah” pasti sudah tidak asing lagi di telinga Anda. Minimal, Anda telah menemukan pengubah akses (publik, pribadi) dan pengubah statis. Hari ini kita akan berbicara tentang pengubah akhir khusus . Hal ini dapat dikatakan untuk “memperkuat” area-area program kita di mana kita memerlukan perilaku yang konstan, tidak ambigu, dan tidak berubah. Ini dapat digunakan dalam tiga area program kami: kelas, metode, dan variabel. Tidak dapat diubah di Java: final, konstanta, dan Tidak dapat diubah - 2 Mari kita bahas satu per satu. Jika deklarasi kelas berisi pengubah akhir , ini berarti Anda tidak dapat mewarisi kelas ini. Dalam kuliah sebelumnya, kita melihat contoh sederhana pewarisan: kita memiliki kelas induk Animal, dan dua kelas anak - CatdanDog
public class Animal {
}

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

public class Dog extends Animal {

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

}

public class Cat extends Animal {

   //ошибка! Cannot inherit from final Animal
}
Kompiler segera menghasilkan kesalahan. Ada banyak -kelas yang sudah diimplementasikan di Java final. Yang paling terkenal yang selalu Anda gunakan adalah String. Selain itu, jika suatu kelas dideklarasikan sebagai final, semua metodenya juga menjadi final. Apa artinya? Jika pengubah ditentukan untuk suatu metode final, metode ini tidak dapat ditimpa. Misalnya, kita memiliki kelas Animalyang mendefinisikan suatu metode voice(). Namun, anjing dan kucing jelas “berbicara” secara berbeda. Oleh karena itu, di setiap kelas - Catdan Dog- kami akan membuat metode voice(), tetapi kami akan mengimplementasikannya secara berbeda.
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!");
   }
}
Di kelas Catdan Dogkami telah mengganti metode kelas induk. Sekarang hewan tersebut akan bersuara tergantung pada kelas objeknya:
public class Main {

   public static void main(String[] args) {

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

       cat.voice();
       dog.voice();
   }
}
Kesimpulan: Meong! Pakan! Namun, jika Animalkita mendeklarasikan suatu metode di suatu kelas voice()sebagai final, maka metode tersebut tidak dapat didefinisikan ulang di 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 kita akan dipaksa untuk menggunakan metode voice()seperti yang didefinisikan di kelas induk:
public static void main(String[] args) {

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

   cat.voice();
   dog.voice();
}
Kesimpulan: Suara! Suara! Sekarang tentang final-variabel. Kalau tidak, mereka disebut konstanta . Pertama (dan yang paling penting), nilai pertama yang ditetapkan ke sebuah konstanta tidak dapat diubah. Itu ditugaskan sekali dan untuk selamanya.
public class Main {

   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;//ошибка! Нельзя присвоить новое meaning final-переменной!
   }
}
Konstanta tidak perlu segera diinisialisasi. Ini bisa dilakukan nanti. Namun nilai yang diberikan pertama kali akan tetap ada selamanya.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;//так делать можно
}
Kedua, perhatikan nama variabel kita. Konstanta Java memiliki konvensi penamaan yang berbeda. Ini bukan camelCase yang biasa kita gunakan. Dalam kasus variabel biasa, kita akan menyebutnya ConstantExample, tetapi nama konstanta ditulis dengan huruf kapital, dan di antara kata-kata (jika ada beberapa) ada garis bawah - “CONSTANT_EXAMPLE”. Mengapa konstanta diperlukan? Misalnya, mereka akan berguna jika Anda terus-menerus menggunakan beberapa nilai konstan dalam suatu program. Katakanlah Anda memutuskan untuk mencatat sejarah dan menulis game "The Witcher 4" sendirian. Game ini jelas akan selalu menggunakan nama karakter utama - “Geralt of Rivia”. Lebih baik pisahkan baris ini dan nama-nama pahlawan lainnya menjadi sebuah konstanta: nilai yang Anda perlukan akan disimpan di satu tempat, dan Anda pasti tidak akan membuat kesalahan saat mengetiknya untuk yang kesekian kalinya.
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-nama karakter menjadi konstanta, dan sekarang kami pasti tidak akan salah mengejanya, dan tidak perlu menulisnya dengan tangan setiap saat. Kelebihan lainnya: jika pada akhirnya kita perlu mengubah nilai variabel di seluruh program, cukup melakukannya di satu tempat, daripada mengulanginya secara manual di seluruh kode :)

Tipe yang tidak dapat diubah

Selama Anda bekerja di Java, Anda mungkin sudah terbiasa dengan kenyataan bahwa programmer hampir sepenuhnya mengontrol keadaan semua objek. Dicari - membuat objek Cat. Jika saya mau, saya mengganti namanya. Jika dia mau, dia mengubah umurnya, atau yang lainnya. Namun di Java ada beberapa tipe data yang mempunyai keadaan khusus. Mereka tidak dapat diubah , atau tidak dapat diubah . Artinya jika suatu kelas tidak dapat diubah, keadaan objeknya tidak dapat diubah. Contohnya? Anda mungkin terkejut, tetapi contoh kelas Immutable yang paling terkenal adalah String! Tampaknya kita tidak dapat mengubah nilai sebuah string? Mari mencoba:
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 Setelah kami menulis:
str1 = "I love Python";
objek dengan string "Saya suka Java" tidak berubah dan tidak hilang kemana-mana. Itu ada dengan aman dan memiliki teks yang persis sama di dalamnya seperti sebelumnya. Kode:
str1 = "I love Python";
baru saja membuat objek lain dan sekarang variabel str1menunjuk ke sana. Tapi kita tidak bisa mempengaruhi objek “Saya suka Java” dengan cara apapun. Oke, mari kita coba secara berbeda! Kelas ini Stringpenuh dengan metode, dan beberapa di antaranya tampaknya mengubah status baris! Misalnya ada metode replace(). Mari kita ubah kata “Java” menjadi kata “Python” di baris kita!
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 Tidak berhasil lagi! Mungkin metode kurva tidak berhasil? Mari kita coba yang lain. Misalnya, substring(). Memangkas string berdasarkan jumlah karakter yang dikirimkan. Mari kita pangkas karakter kita menjadi 10 karakter 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 Tidak dapat diubah di Java: final, konstanta, dan Tidak dapat diubah - 3 Tidak ada yang berubah. Dan itu tidak seharusnya terjadi. Seperti yang kami katakan, objek Stringtidak dapat diubah. Lalu apa semua metode kelas ini String? Mereka dapat memangkas garis, mengubah karakter di dalamnya, dll. Mengapa mereka dibutuhkan jika tidak terjadi apa-apa? Mereka bisa! Tapi mereka mengembalikan objek string baru setiap kali. Tidak ada gunanya menulis:
str1.replace("Java", "Python");
- Anda tidak akan mengubah objek aslinya. Tetapi jika Anda menulis hasil metode tersebut ke dalam variabel referensi baru, Anda akan langsung melihat perbedaannya!
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);
}
Inilah satu-satunya cara agar semua metode ini Stringberhasil. Anda tidak dapat melakukan apa pun dengan objek "Saya suka Java" . Buat saja objek baru dan tulis: “Objek baru = hasil beberapa manipulasi dengan objek “Saya suka Java” .” Tipe lain apa yang tidak dapat diubah? Dari apa yang perlu Anda ingat sekarang - semua kelas pembungkus pada tipe primitif tidak dapat diubah. Integer, Byte, Character, Short, Boolean, Long, Double, Float- semua kelas ini membuat objek yang tidak dapat diubah . Ini juga mencakup kelas yang digunakan untuk membuat bilangan besar - BigIntegerdan BigDecimal. Kami baru-baru ini membahas pengecualian dan membahasnya StackTrace. Jadi: objek kelas java.lang.StackTraceElement juga tidak dapat diubah. Ini logis: jika seseorang dapat mengubah data di tumpukan kami, hal itu dapat meniadakan semua pekerjaan yang dilakukan dengannya. Bayangkan seseorang masuk ke StackTrace dan mengubah OutOfMemoryError menjadi FileNotFoundException . Dan Anda harus bekerja dengan tumpukan ini dan mencari penyebab kesalahannya. Dan program ini tidak menggunakan file sama sekali :) Oleh karena itu, untuk amannya, objek-objek ini dibuat tidak dapat diubah. Ya, dengan StackTraceElement kurang lebih jelas. Mengapa ada orang yang ingin membuat string tidak dapat diubah? Apa jadinya jika nilai-nilai mereka bisa diubah. Mungkin akan lebih nyaman :/ Ada beberapa alasan untuk ini. Pertama, menghemat memori. String yang tidak dapat diubah dapat ditempatkan String Pooldan string yang sama dapat digunakan setiap kali alih-alih membuat string baru. Kedua, keamanan. Misalnya, sebagian besar login dan kata sandi dalam program apa pun adalah string. Kemungkinan untuk mengubahnya dapat menimbulkan masalah dengan otorisasi. Ada alasan lain, namun kami belum membahasnya saat mempelajari Java—kami akan kembali lagi nanti.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION