CodeGym/Java blog/Véletlen/Rögzített értékek a Java-ban: végleges, állandók és megvá...
John Squirrels
Szint
San Francisco

Rögzített értékek a Java-ban: végleges, állandók és megváltoztathatatlan

Megjelent a csoportban
Szia! Ön már ismeri a "módosító" szót. Legalább hozzáférésmódosítókkal (nyilvános, privát) és statikus módosítóval találkozott. Ma egy speciális módosítóról fogunk beszélni, a végleges . Mondhatni az utolsó módosító „becementálja” programunk azon részeit, ahol állandó, egyértelmű, változatlan viselkedésre van szükség. A programokban három helyen használhatja: osztályok, metódusok és változók. Rögzített értékek a Java nyelvben: végleges, állandók és megváltoztathatatlan - 2 Fussunk végig rajtuk sorban. Ha a végső módosítót egy osztálydeklarációban használjuk, az azt jelenti, hogy az osztály nem örökölhető. Az előző leckéken egy egyszerű öröklési példát használtunk: volt egy Animalszülői és két gyerekosztályunk: CatésDog
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
}
Ha azonban a végső módosítót használjuk az Animalosztályon, a Catés Dogosztályok nem örökölhetik azt.
public final class Animal {

}

public class Cat extends Animal {

   // Error! Cannot inherit from final Animal
}
A fordító azonnal hibát generál. A Java nyelven sok végső osztály már implementálva van. Azok közül, amelyeket gyakran használ, Stringa legismertebb. Sőt, ha egy osztályt véglegesnek nyilvánítanak , akkor az osztály összes metódusa is véglegessé válik . Az mit jelent? Ha egy metódus a végső módosítóval van deklarálva , akkor nem bírálhatja felül azt. Például itt van egy Animalosztály, amely deklarál egy speak()metódust. De a kutyák és a macskák határozottan különböző módon "beszélnek". CatTehát a és az osztályokban is deklaráljuk a speak() metódusokat Dog, de másképpen implementáljuk őket.
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!");
   }
}
CatA és osztályokat felülírtuk Doga szülőosztályban deklarált metóduson. Most egy állat másképp fog beszélni, attól függően, hogy milyen típusú tárgyról van szó:
public class Main {

   public static void main(String[] args) {

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

       cat.speak();
       dog.speak();
   }
}
Kimenet: Miau! Szövet! AnimalHa azonban az osztály speak()metódusát véglegesnek nyilvánítjuk , akkor más osztályokban nem tudjuk felülírni:
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!");
   }
}
És objektumaink kénytelenek lesznek speak()a szülőosztályban meghatározott metódus használatára:
public static void main(String[] args) {

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

   cat.speak();
   dog.speak();
}
Kimenet: Hello! Helló! Most a végső változókkal kapcsolatban. Állandónak is nevezik őket . Először is (és ami a legfontosabb) az állandó értékhez rendelt kezdeti érték nem módosítható. Egyszer s mindenkorra hozzá van rendelve.
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!
   }
}
Egy állandót nem kell azonnal inicializálni. Ezt később meg lehet tenni. De az eredetileg hozzárendelt érték örökre ugyanaz marad.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;// This is allowed
}
Másodszor, jegyezzük meg a változónk nevét. A Java eltérő elnevezési konstansokkal rendelkezik a konstansok számára. Ez nem a szokásos camelCase jelölés. Ha egy közönséges változó lett volna, akkor állandóPéldának neveztük volna. De az állandók nevei csupa nagybetűvel vannak írva, a szavak közé aláhúzással (ha több szó van), pl. "CONSTANT_EXAMPLE". Miért van szükségünk állandókra? Nagyon hasznosak, ha például van egy rögzített érték, amelyet rendszeresen használ egy programban. Például úgy döntött, hogy történelmet ír, és maga írja meg a „The Witcher 4” játékot. A játék nyilvánvalóan rendszeresen használja majd a főszereplő nevét: "Geralt of Rivia". Ezt a karakterláncot (és más hősök nevét) a legjobb konstansként deklarálni: az értéke egy helyen lesz tárolva, és biztosan nem követ el elírást milliószori beíráskor.
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");
   }
}
Kimenet: The Witcher 4 Ez már a negyedik Witcher játék, de Geralt of Rivia még mindig nem tudja eldönteni, kit szeret jobban: Yennefer of Wengerberget vagy Triss Merigoldot. De ha még soha nem játszott a The Witcherrel, akkor a kezdet. A főszereplő neve Riviai Geralt. Riviai Geralt witcher, szörnyvadász. A hősök nevét állandónak nyilvánítottuk. Most biztosan nem fogunk elgépelési hibákat elkövetni, és nem kell minden alkalommal kézzel kiírni őket. Egy másik plusz: ha valaha is módosítanunk kell a változó értékét a teljes programban, akkor azt egy helyen megteheti, ahelyett, hogy manuálisan módosítaná a teljes kódbázison. :)

Változhatatlan típusok

Miközben a Java-val dolgozott, valószínűleg már megszokta azt a gondolatot, hogy a programozók szinte teljes mértékben kontrollálják az összes objektum állapotát. Ha objektumot szeretne létrehozni Cat, megteheti. Ha át akarja nevezni, megteheti. Ha módosítani szeretné a korát vagy valami mást, megteheti. De a Java-nak számos adattípusa van, amelyeknek speciális tulajdonsága van. Megváltoztathatatlanok . _ Ha egy osztály megváltoztathatatlan, akkor az objektumok állapota nem változtatható meg. Szeretnél néhány példát? Meglephet, de a legismertebb megváltoztathatatlan osztály a String! Szóval tényleg nem tudjuk megváltoztatni egy karakterlánc értékét? Nos, próbáljuk ki:
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
}
Kimenet: Imádom a Java-t Imádom a Java-t Miután megírtuk
str1 = "I love Python";
a "I love Java"string objektum nem változott vagy nem ment sehova. Még mindig boldogan létezik, és pontosan ugyanaz a szövege van, mint korábban. A kód
str1 = "I love Python";
egyszerűen létrehozott egy másik objektumot, amelyre az str1 most mutat. De úgy tűnik, hogy nem tudunk semmilyen hatással lenni az „I love Java” karakterlánc objektumra. Oké, próbáljunk ki valami mást! Az Stringosztály tele van metódusokkal, és némelyikük megváltoztatja az objektum állapotát! Például van egy replace()módszer. Változtassuk meg a „Java” szót „Python”-ra a karakterláncunkban!
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);
}
Kimenet: Imádom a Java-t Imádom a Java-t Ez megint nem működött! Lehet, hogy a csere módszer nem működik? Próbáljunk meg valami mást. Például, substring(). Az argumentumként átadott karakterindexek alapján egy részkarakterláncot ad vissza. Vágjuk le a karakterláncunk első 10 karakterét:
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);
}
Kimenet: Imádom a Java-t Imádom a Java-t Rögzített értékek a Java nyelvben: végleges, állandók és megváltoztathatatlan - 3 Semmi sem változott. És nem kellett volna. Ahogy korábban mondtuk, a húrok megváltoztathatatlanok. Szóval, mi a helyzet az osztály összes metódusával String? Végtére is csonkolhatják a karakterláncokat, megváltoztathatják a karaktereket stb. Mi értelme van, ha nem történik semmi? Valójában meg tudják csinálni ezeket a dolgokat! De minden alkalommal új karakterláncot adnak vissza. Felesleges írni
str1.replace("Java", "Python");
mert az eredeti objektumot nem tudod megváltoztatni. De ha a metódus eredményét egy új referenciaváltozóba írod, azonnal látni fogod a különbséget!
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);
}
Minden Stringmódszer így működik. A tárggyal semmit nem lehet tenni "I love Java". Létrehozhat egy új objektumot, és beírhatja: "<új objektum> = a . manipulációjának eredménye "I love Java" object ". Milyen más típusok változtathatatlanok? Néhányat, amelyet azonnal meg kell jegyeznie, a primitív típusok összes burkoló osztálya. Integer, Byte, Character, Short, Boolean, Long, Double, Float: ezek az osztályok mindegyike immutableobjektumokat hoz létre (a következő leckékben beszélünk róluk). Ide tartoznak a nagy számok létrehozására használt osztályok, mint például a BigIntegerés BigDecimal. Nemrég foglalkoztunk a kivételekkel, és érintettük a verem nyomkövetését . , tippeld ki, java.lang.StackTraceElementa tárgyak is megváltoztathatatlanok. Ez logikus: ha valaki módosítani tudná a veremünk adatait, az értelmetlenné tenné az egészet. Képzelje el, hogy valaki végigmegy a verem nyomon, és egy OutOfMemoryError-t FileNotFoundException- re változtat . Ezután a verem segítségével keresse meg a hiba okát. De a program nem is használ fájlokat. :) Szóval megváltoztathatatlanná tették ezeket a tárgyakat, minden esetre. Oké, szóval ez többé-kevésbé értelmes a StackTraceElement számára . De miért kellene bárkinek megváltoztathatatlanná tennie a Strings-t? Miért lenne probléma az értékrendjük megváltoztatása? Valószínűleg még kényelmesebb is lenne. :/ Ennek több oka is van. Először is memóriát takarít meg. A húrkészletben változtathatatlan húrok helyezhetők el, amely lehetővé teszi a karakterláncok újrafelhasználását újak létrehozása helyett. Másodszor a biztonság kedvéért. Például a felhasználónevek és jelszavak szinte minden programban karakterláncok. A módosítások engedélyezése engedélyezési problémákat okozhat. Vannak más okok is, de a Java-tanulmányunk még nem tért ki rájuk, ezért később visszatérünk rájuk.
Hozzászólások
  • Népszerű
  • Új
  • Régi
Hozzászólás írásához be kell jelentkeznie
Ennek az oldalnak még nincsenek megjegyzései