CodeGym /Java Blog /Random /Mga fixed value sa Java: final, constants, at immutable
John Squirrels
Antas
San Francisco

Mga fixed value sa Java: final, constants, at immutable

Nai-publish sa grupo
Hi! Pamilyar ka na sa salitang "modifier". Sa pinakamababa, nakatagpo ka ng mga modifier ng access (pampubliko, pribado) at ang static na modifier. Ngayon ay tatalakayin natin ang isang espesyal na modifier na tinatawag na final . Maaari mong sabihin ang panghuling modifier na "mga semento" na bahagi ng aming programa kung saan kailangan ang pare-pareho, hindi malabo, hindi nagbabagong pag-uugali. May tatlong lugar sa iyong mga program na magagamit mo ito: mga klase, pamamaraan, at mga variable. Mga nakapirming halaga sa Java: final, constants, at immutable - 2 Patakbuhin natin ang mga ito sa pagkakasunud-sunod. Kung ang panghuling modifier ay ginamit sa isang deklarasyon ng klase, nangangahulugan ito na hindi maaaring mamana ang klase. Sa nakaraang mga aralin, gumamit kami ng isang simpleng halimbawa ng pamana: mayroon kaming isang Animalklase ng magulang at dalawang klase ng bata: CatatDog

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
}
Gayunpaman, kung gagamitin natin ang panghuling modifier sa Animalklase, hindi ito mamanahin ng Catat Dogmga klase.

public final class Animal {

}

public class Cat extends Animal {

   // Error! Cannot inherit from final Animal
}
Ang compiler ay agad na bumubuo ng isang error. Sa Java, maraming panghuling klase ang naipatupad na. Kabilang sa mga madalas mong ginagamit, Stringay ang pinakakilala. Bukod dito, kung ang isang klase ay idineklara bilang final , ang lahat ng mga pamamaraan ng klase ay magiging final . Anong ibig sabihin niyan? Kung ang isang paraan ay idineklara gamit ang panghuling modifier, hindi mo maaaring i-override ang pamamaraang iyon. Halimbawa, dito mayroon kaming isang Animalklase na nagdedeklara ng isang speak()pamamaraan. Ngunit, ang mga aso at pusa ay tiyak na "nagsalita" sa iba't ibang paraan. Kaya, idedeklara namin ang mga pamamaraan ng speak() sa parehong Catat Dogmga klase, ngunit ipapatupad namin ang mga ito nang iba.

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!");
   }
}
Ginawa naming i-override ang Catat Dogmga klase sa pamamaraang idineklara sa parent class. Ngayon, iba ang pagsasalita ng isang hayop, depende sa kung anong uri ng bagay ito:

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();
      
       cat.speak();
       dog.speak();
   }
}
Output: Meow! Woof! Gayunpaman, kung idedeklara namin ang pamamaraan Animalng klase speak()bilang pangwakas, hindi namin ito ma-override sa ibang mga klase:

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!");
   }
}
At ang aming mga bagay ay mapipilitang gamitin ang speak()pamamaraan tulad ng tinukoy sa parent class:

public static void main(String[] args) {

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

   cat.speak();
   dog.speak();
}
Output: Hello! Kamusta! Ngayon, tungkol sa mga huling variable. Ang mga ito ay kilala rin bilang mga constants . Una (at pinaka-mahalaga), ang paunang halaga na itinalaga sa isang pare-parehong halaga ay hindi mababago. Ito ay itinalaga minsan at para sa lahat.

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!
   }
}
Ang isang pare-pareho ay hindi kailangang masimulan kaagad. Mamaya pwede na yan. Ngunit, ang halaga na unang itinalaga dito ay mananatiling pareho magpakailanman.

public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;// This is allowed
}
Pangalawa, tandaan ang pangalan ng aming variable. Ang Java ay may ibang kombensyon ng pagbibigay ng pangalan para sa mga constants. Hindi ito ang karaniwang notasyon ng camelCase . Kung ito ay isang ordinaryong variable, tatawagin namin itong constantExample. Ngunit, ang mga pangalan ng mga constant ay nakasulat sa lahat ng caps, na may mga underscore sa pagitan ng mga salita (kung mayroong higit sa isang salita), hal. "CONSTANT_EXAMPLE". Bakit kailangan natin ng mga constants? Ang mga ito ay lubhang kapaki-pakinabang kung, halimbawa, mayroong isang nakapirming halaga na regular mong ginagamit sa isang programa. Halimbawa, nagpasya kang gumawa ng kasaysayan at isulat ang larong "The Witcher 4" nang mag-isa. Malinaw na regular na gagamitin ng laro ang pangalan ng pangunahing tauhan: "Geralt of Rivia". Ang string na ito (at mga pangalan ng iba pang mga bayani) ay pinakamahusay na ipinahayag bilang isang pare-pareho: ang halaga nito ay maiimbak sa isang lugar, at tiyak na hindi ka gagawa ng typo kapag ipinasok ito ng isang milyong beses.

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");
   }
}
Output: The Witcher 4 Ito na ang ikaapat na laro ng Witcher, ngunit hindi pa rin makapagpasya si Geralt ng Rivia kung sino ang mas gusto niya: Yennefer ng Wengerberg o Triss Merigold Ngunit, kung hindi ka pa nakakalaro ng The Witcher dati, magsisimula tayo sa simula. Ang pangalan ng bida ay Geralt ng Rivia Si Geralt ng Rivia ay isang mangkukulam, isang halimaw na mangangaso Idineklara namin ang mga pangalan ng mga bayani bilang mga constant. Ngayon ay tiyak na hindi na tayo gagawa ng typo, at hindi na kailangang isulat ang mga ito gamit ang kamay sa bawat pagkakataon. Isa pang plus: kung kailangan nating baguhin ang value ng variable sa buong program, magagawa mo ito sa isang lugar, sa halip na manu-manong baguhin ito sa buong code base. :)

Mga uri na hindi nababago

Habang nagtrabaho ka sa Java, malamang na nasanay ka na sa ideya na ang mga programmer ay may halos kumpletong kontrol sa estado ng lahat ng mga bagay. Kung nais mong lumikha ng isang Catbagay, magagawa mo. Kung gusto mong palitan ang pangalan nito, maaari mo. Kung gusto mong baguhin ang edad nito o iba pa, magagawa mo. Ngunit ang Java ay may ilang uri ng data na may espesyal na pag-aari. Sila ay hindi nababago . Kung ang isang klase ay hindi nababago, ang estado ng mga bagay nito ay hindi mababago. Gusto ng ilang mga halimbawa? Maaaring magulat ka, ngunit ang pinakakilalang hindi nababagong klase ay ang String! Kaya, talagang hindi natin mababago ang halaga ng isang String? Well, subukan natin ito:

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
}
Output: I love Java I love Java After we wrote

str1 = "I love Python";
ang "I love Java"string object ay hindi nagbago o pumunta kahit saan. Masaya pa rin itong umiiral at may eksaktong parehong teksto tulad ng dati. Ang code

str1 = "I love Python";
lumikha lamang ng isa pang bagay, na itinuturo ngayon ng str1 . Ngunit, mukhang wala tayong epekto sa string object na "I love Java". Okay, subukan natin ang iba pa! Ang Stringklase ay puno ng mga pamamaraan, at ang ilan sa mga ito ay lumilitaw na nagbabago sa estado ng bagay! Halimbawa, mayroong isang replace()pamamaraan. Baguhin natin ang salitang "Java" sa "Python" sa ating string!

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);
}
Output: Mahal ko ang Java Gusto ko ang Java Hindi na ito gumana muli! Siguro ang paraan ng pagpapalit ay hindi gumagana? Subukan natin ang iba pa. Halimbawa, substring(). Nagbabalik ito ng substring batay sa mga indeks ng character na ipinasa bilang mga argumento. Putulin natin ang unang 10 character ng ating string:

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);
}
Output: Mahal ko ang Java Mahal ko ang Java Mga nakapirming halaga sa Java: final, constants, at immutable - 3 Walang nagbago. At hindi dapat. Tulad ng sinabi namin kanina, ang Strings ay hindi nababago. Kaya, ano ang lahat ng mga pamamaraan sa Stringklase? Pagkatapos ng lahat, maaari nilang putulin ang mga string, baguhin ang mga character, at higit pa. What's the point kung walang mangyayari? Magagawa talaga nila ang mga bagay na ito! Ngunit, nagbabalik sila ng bagong String sa bawat oras. Walang kwenta ang magsulat

str1.replace("Java", "Python");
dahil hindi mo mababago ang orihinal na bagay. Ngunit, kung isusulat mo ang resulta ng pamamaraan sa isang bagong reference na variable, makikita mo kaagad ang pagkakaiba!

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);
}
Ang lahat Stringng mga pamamaraan ay gumagana sa ganitong paraan. Walang magagawa sa "I love Java"bagay. Maaari ka lang gumawa ng bagong object at isulat ang: "<new object> = ang resulta ng pagmamanipula ng "I love Java" object ". Ano pang mga uri ang hindi nababago? Ang ilan na tiyak na kailangan mong tandaan kaagad ay ang lahat ng mga klase ng wrapper para sa mga primitive na uri. Integer, Byte, Character, Short, Boolean, Long, Double, Float: lahat ng klaseng ito ay lumilikha ng immutablemga bagay (pag-uusapan natin ang tungkol sa mga ito sa paparating na mga aralin). Kabilang dito ang mga klase na ginamit upang lumikha ng malalaking numero, gaya ng BigIntegerat BigDecimal. Kamakailan ay sinakop namin ang mga pagbubukod at hinawakan ang stack trace . Well , hulaan mo, java.lang.StackTraceElementang mga bagay ay hindi rin nababago. Makatuwiran ito: kung maaaring baguhin ng isang tao ang data ng aming stack, gagawin nitong walang kabuluhan ang buong bagay. Isipin na may dumaan sa stack trace at nagpapalit ng OutOfMemoryError sa isang FileNotFoundException . At pagkatapos ay gagamitin mo ang stack na iyon upang mahanap ang sanhi ng error. Ngunit ang programa ay hindi kahit na gumagamit ng mga file. :) Kaya, ginawa nilang hindi nababago ang mga bagay na ito, kung sakali. Okay, kaya mas may katuturan ito para sa StackTraceElement . Ngunit, bakit kailangan ng sinuman na gawing hindi nababago ang Strings? Bakit magiging problema ang pagbabago ng kanilang mga halaga? Ito ay malamang na maging mas maginhawa. :/ Mayroong ilang mga dahilan para dito. Una, nakakatipid ito ng memorya. Ang mga hindi nababagong string ay maaaring ilagay sa string pool, na nagpapahintulot sa mga string na magamit muli sa halip na lumikha ng mga bago. Pangalawa, para sa seguridad. Halimbawa, ang mga username at password ay Strings sa halos bawat programa. Ang paggawang posible na baguhin ang mga ito ay maaaring magresulta sa mga problema sa pahintulot. Mayroong iba pang mga kadahilanan, ngunit hindi pa saklaw ng aming pag-aaral ng Java, kaya babalikan namin ang mga ito mamaya.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION