CodeGym /Java Blog /Acak /Nilai tetap di Java: final, konstanta, dan tidak dapat di...
John Squirrels
Level 41
San Francisco

Nilai tetap di Java: final, konstanta, dan tidak dapat diubah

Dipublikasikan di grup Acak
Hai! Anda pasti sudah tidak asing lagi dengan kata "pengubah". Setidaknya, Anda pernah menemukan pengubah akses (publik, pribadi) dan pengubah statis. Hari ini kita akan membahas pengubah khusus yang disebut final . Bisa dibilang pengubah terakhir "menyemen" bagian dari program kami di mana diperlukan perilaku yang konstan, tidak ambigu, dan tidak berubah. Ada tiga tempat di program Anda yang dapat Anda gunakan: kelas, metode, dan variabel. Nilai tetap di Jawa: final, konstanta, dan tidak berubah - 2 Mari kita bahas secara berurutan. Jika pengubah final digunakan dalam deklarasi kelas, itu berarti kelas tersebut tidak dapat diwariskan. Dalam pelajaran sebelumnya, kami menggunakan contoh pewarisan sederhana: kami memiliki Animalkelas induk dan dua kelas anak: CatdanDog

public class Animal {
}



public class Cat extends Animal {
   // Fields and methods of the Cat class
}


public class Dog extends Animal {

   // Fields and methods of the Dog class
}
Namun, jika kita menggunakan pengubah final pada Animalkelas, kelas Catdan Dogtidak dapat mewarisinya.

public final class Animal {

}

public class Cat extends Animal {

   // Error! Cannot inherit from final Animal
}
Kompiler segera menghasilkan kesalahan. Di Jawa, banyak final class sudah diimplementasikan. Di antara yang sering Anda gunakan, Stringadalah yang paling terkenal. Selain itu, jika sebuah kelas dideklarasikan sebagai final , semua metode kelas tersebut juga menjadi final . Maksudnya itu apa? Jika suatu metode dideklarasikan menggunakan pengubah akhir , Anda tidak dapat mengganti metode tersebut. Misalnya, di sini kita memiliki Animalkelas yang mendeklarasikan speak()metode. Tapi, anjing dan kucing pasti "berbicara" dengan cara yang berbeda. Jadi, kami akan mendeklarasikan metode speak() di kelas Catdan Dog, tetapi kami akan menerapkannya secara berbeda.

public class Animal {
  
   public void speak() {
       System.out.println("Hello!");
   }
}

public class Cat extends Animal {

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

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}
Kami membuat kelas Catand Dogmenggantikan metode yang dideklarasikan di kelas induk. Sekarang, seekor binatang akan berbicara secara berbeda, tergantung pada jenis objeknya:

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();
      
       cat.speak();
       dog.speak();
   }
}
Keluaran: Meong! Pakan! Namun, jika kita mendeklarasikan metode Animalkelas speak()sebagai final, kita tidak dapat menimpanya di kelas lain:

public class Animal {

   public final void speak() {
       System.out.println("Hello!");
   }
}


public class Cat extends Animal {

   @Override
   public void speak() {// Error! A final method can't be overridden!
       System.out.println("Meow!");
   }
}
Dan objek kita akan dipaksa untuk menggunakan speak()metode seperti yang didefinisikan di kelas induk:

public static void main(String[] args) {

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

   cat.speak();
   dog.speak();
}
Keluaran: Halo! Halo! Sekarang, tentang variabel akhir . Mereka juga dikenal sebagai konstanta . Pertama (dan yang terpenting), nilai awal yang ditetapkan ke nilai konstanta tidak dapat diubah. Itu ditugaskan sekali dan untuk semua.

public class Main {
  
   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;// Error! You can't assign a new value to a final variable!
   }
}
Konstanta tidak perlu diinisialisasi dengan segera. Itu bisa dilakukan nanti. Namun, nilai yang awalnya diberikan padanya akan tetap sama selamanya.

public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;// This is allowed
}
Kedua, catat nama variabel kita. Java memiliki konvensi penamaan yang berbeda untuk konstanta. Ini bukan notasi camelCase biasa . Jika itu adalah variabel biasa, kita akan menyebutnya sebagai ConstantExample. Namun, nama konstanta ditulis dengan huruf besar semua, dengan garis bawah di antara kata (jika ada lebih dari satu kata), misalnya "CONSTANT_EXAMPLE". Mengapa kita membutuhkan konstanta? Mereka sangat berguna jika, misalnya, ada nilai tetap yang biasa Anda gunakan dalam suatu program. Misalnya, Anda memutuskan untuk membuat sejarah dan menulis game "The Witcher 4" sendiri. Gim ini jelas akan sering menggunakan nama protagonis: "Geralt of Rivia". String ini (dan nama pahlawan lainnya) paling baik dideklarasikan sebagai konstanta: nilainya akan disimpan di satu tempat, dan Anda pasti tidak akan salah ketik saat memasukkannya jutaan kali.

public class TheWitcher4 {

   private static final String GERALT_NAME = "Geralt of Rivia";
   private static final String YENNEFER_NAME = "Yennefer of Wengerberg";
   private static final String TRISS_NAME = "Triss Merigold";

   public static void main(String[] args) {

       System.out.println("The Witcher 4");
       System.out.println("It's already the fourth Witcher game, but " + GERALT_NAME + " still can't decide who" +
               " he likes more: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("But, if you've never played The Witcher before, we'll start from the beginning.");
       System.out.println("The protagonist's name is " + GERALT_NAME);
       System.out.println(GERALT_NAME + " is a witcher, a monster hunter");
   }
}
Keluaran: The Witcher 4 Ini sudah game Witcher keempat, tetapi Geralt of Rivia masih belum bisa memutuskan siapa yang lebih disukainya: Yennefer of Wengerberg atau Triss Merigold Tapi, jika Anda belum pernah memainkan The Witcher sebelumnya, kami akan mulai dari awal. Nama protagonisnya adalah Geralt of Rivia Geralt of Rivia adalah seorang penyihir, pemburu monster Kami telah menyatakan nama para pahlawan sebagai konstanta. Sekarang kami pasti tidak akan salah ketik, dan tidak perlu menulisnya dengan tangan setiap saat. Kelebihan lainnya: jika kita perlu mengubah nilai variabel di seluruh program, Anda dapat melakukannya di satu tempat, daripada memodifikasinya secara manual di seluruh basis kode. :)

Jenis yang tidak dapat diubah

Karena Anda telah bekerja dengan Java, Anda mungkin sudah terbiasa dengan gagasan bahwa pemrogram hampir memiliki kendali penuh atas status semua objek. Jika Anda ingin membuat Catobjek, Anda bisa. Kalau mau ganti nama juga bisa. Jika Anda ingin mengubah usianya atau yang lainnya, Anda bisa. Namun Java memiliki beberapa tipe data yang memiliki properti khusus. Mereka tidak berubah . Jika suatu kelas tidak dapat diubah, maka status objeknya tidak dapat diubah. Ingin beberapa contoh? Ini mungkin mengejutkan Anda, tetapi kelas abadi yang paling terkenal adalah String! Jadi, kita benar-benar tidak bisa mengubah nilai sebuah String? Baiklah, mari kita coba:

public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1 = "I love Python";// but changing str1 has no impact on str2
   System.out.println(str2);// str2 continues to point to the "I love Java" string, but str1 now points to a different object
}
Keluaran: Saya suka Java, saya suka Java Setelah kami menulis

str1 = "I love Python";
objek "I love Java"string tidak berubah atau pergi ke mana pun. Itu masih ada dengan senang hati dan memiliki teks yang sama persis seperti sebelumnya. Kode

str1 = "I love Python";
cukup buat objek lain, yang sekarang ditunjuk oleh str1 . Namun, sepertinya kami tidak dapat memberikan efek apa pun pada objek string "I love Java". Oke, mari kita coba yang lain! Kelas Stringpenuh dengan metode, dan beberapa di antaranya tampaknya mengubah keadaan objek! Misalnya, ada replace()metode. Mari kita ubah kata "Java" menjadi "Python" di string kita!

public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1.replace("Java", "Python");// We try to change the state of str1 by swapping the word "Java" with "Python"
   System.out.println(str2);
}
Keluaran: Saya suka Java Saya suka Java Tidak berhasil lagi! Mungkin metode penggantian tidak berfungsi? Mari kita coba sesuatu yang lain. Misalnya, substring(). Ini mengembalikan substring berdasarkan indeks karakter yang diteruskan sebagai argumen. Mari kita potong 10 karakter pertama dari string kita:

public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1.substring(10);// Truncate the original String 
   System.out.println(str2);
}
Keluaran: Saya suka Java Saya suka Java Nilai tetap di Jawa: final, konstanta, dan tidak berubah - 3 Tidak ada yang berubah. Dan seharusnya tidak. Seperti yang kami katakan sebelumnya, String tidak dapat diubah. Jadi, ada apa dengan semua metode di kelas String? Lagi pula, mereka dapat memotong string, mengubah karakter, dan banyak lagi. Apa gunanya jika tidak ada yang terjadi? Mereka benar-benar dapat melakukan hal-hal ini! Tapi, mereka mengembalikan String baru setiap saat. Tidak ada gunanya menulis

str1.replace("Java", "Python");
karena Anda tidak dapat mengubah objek aslinya. Namun, jika Anda menuliskan hasil metode ke variabel referensi baru, Anda akan segera melihat perbedaannya!

public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

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

   System.out.println(str1AfterReplacement);
}
Semua Stringmetode bekerja dengan cara ini. Tidak ada yang bisa dilakukan pada "I love Java"objek. Anda cukup membuat objek baru dan menulis: "<new object> = hasil manipulasi "I love Java" object ". Jenis lain apa yang tidak dapat diubah? Beberapa yang harus segera Anda ingat adalah semua kelas pembungkus untuk jenis primitif. Integer, Byte, Character, Short, Boolean, Long, , Double, Float: semua kelas ini membuat immutableobjek (kita akan membicarakannya di pelajaran mendatang). Ini termasuk kelas yang digunakan untuk membuat angka besar, seperti BigIntegerdan BigDecimal. Kami baru saja membahas pengecualian dan menyentuh jejak tumpukan . Nah , coba tebak, java.lang.StackTraceElementobjek juga tidak berubah. Ini masuk akal: jika seseorang dapat mengubah data tumpukan kami, semuanya akan sia-sia. Bayangkan seseorang menelusuri jejak tumpukan dan mengubah OutOfMemoryError menjadi FileNotFoundException . Dan kemudian Anda menggunakan tumpukan itu untuk menemukan penyebab kesalahan. Tetapi program tersebut bahkan tidak menggunakan file. :) Jadi, mereka membuat objek ini tidak dapat diubah, untuk berjaga-jaga. Oke, jadi kurang lebih masuk akal untuk StackTraceElement . Tapi, mengapa ada orang yang perlu membuat Strings tidak dapat diubah? Mengapa mengubah nilai-nilai mereka menjadi masalah? Bahkan mungkin akan lebih nyaman. :/ Ada beberapa alasan untuk ini. Pertama, menghemat memori. String yang tidak dapat diubah dapat ditempatkan di kumpulan string, memungkinkan string untuk digunakan kembali alih-alih membuat yang baru. Kedua, untuk keamanan. Misalnya, nama pengguna dan kata sandi adalah String di hampir setiap program. Memungkinkan untuk mengubahnya dapat mengakibatkan masalah otorisasi. Ada alasan lain, tetapi studi kami tentang Jawa belum membahasnya, jadi kami akan kembali lagi nanti.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION