CodeGym/Java-blogg/Tilfeldig/Faste verdier i Java: endelig, konstanter og uforanderlig...
John Squirrels
Nivå
San Francisco

Faste verdier i Java: endelig, konstanter og uforanderlige

Publisert i gruppen
Hei! Du er allerede kjent med ordet "modifikator". Som et minimum har du møtt tilgangsmodifikatorer (offentlige, private) og den statiske modifikatoren. I dag skal vi diskutere en spesiell modifikator kalt final . Du kan si at den siste modifikatoren "sementerer" deler av programmet vårt der konstant, entydig, uforanderlig atferd er nødvendig. Det er tre steder i programmene dine du kan bruke det: klasser, metoder og variabler. Faste verdier i Java: endelig, konstanter og uforanderlige - 2 La oss gå gjennom dem i rekkefølge. Hvis den endelige modifikatoren brukes i en klasseerklæring, betyr det at klassen ikke kan arves. I tidligere leksjoner brukte vi et enkelt arveeksempel: vi hadde en Animalforeldreklasse og to barneklasser: CatogDog
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
}
Men hvis vi bruker den endelige modifikatoren på Animalklassen, kan ikke Catog- Dogklassene arve den.
public final class Animal {

}

public class Cat extends Animal {

   // Error! Cannot inherit from final Animal
}
Kompilatoren genererer umiddelbart en feil. I Java er mange avsluttende klasser allerede implementert. Blant dem du bruker ofte, Stringer den mest kjente. Dessuten, hvis en klasse er erklært som endelig , blir alle klassens metoder også endelige . Hva betyr det? Hvis en metode er deklarert ved å bruke den endelige modifikatoren, kan du ikke overstyre den metoden. For eksempel, her har vi en Animalklasse som erklærer en speak()metode. Men, hunder og katter "snakker" definitivt på forskjellige måter. Så vi vil erklære speak()-metoder i både klassene Catog Dog, men vi vil implementere dem annerledes.
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!");
   }
}
Vi fikk klassene Catog Dogtil å overstyre metoden som er deklarert i overordnet klasse. Nå vil et dyr snakke annerledes, avhengig av hvilken type gjenstand det er:
public class Main {

   public static void main(String[] args) {

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

       cat.speak();
       dog.speak();
   }
}
Utgang: Mjau! Wuff! Men hvis vi erklærer Animalklassens speak()metode som endelig, kan vi ikke overstyre den i andre klasser:
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!");
   }
}
Og objektene våre vil bli tvunget til å bruke speak()metoden som er definert i overordnet klasse:
public static void main(String[] args) {

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

   cat.speak();
   dog.speak();
}
Utgang: Hei! Hallo! Nå, angående endelige variabler. De er også kjent som konstanter . For det første (og viktigst av alt), startverdien tilordnet en konstant verdi kan ikke endres. Det tildeles en gang for alle.
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!
   }
}
En konstant trenger ikke å initialiseres umiddelbart. Det kan gjøres senere. Men verdien som opprinnelig ble tildelt den vil forbli den samme for alltid.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;// This is allowed
}
For det andre, legg merke til variabelens navn. Java har en annen navnekonvensjon for konstanter. Det er ikke den vanlige camelCase- notasjonen. Hvis det hadde vært en ordinær variabel, ville vi kalt den konstantEksempel. Men navnene på konstantene er skrevet med store bokstaver, med understreking mellom ordene (hvis det er mer enn ett ord), f.eks. "CONSTANT_EXAMPLE". Hvorfor trenger vi konstanter? De er veldig nyttige hvis det for eksempel er en fast verdi du jevnlig bruker i et program. For eksempel har du bestemt deg for å lage historie og skrive spillet "The Witcher 4" selv. Spillet vil åpenbart regelmessig bruke hovedpersonens navn: "Geralt of Rivia". Denne strengen (og andre helters navn) er best deklarert som en konstant: verdien vil bli lagret på ett sted, og du vil definitivt ikke skrive en skrivefeil når du skriver den inn en million ganger.
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");
   }
}
Utgang: The Witcher 4 Det er allerede det fjerde Witcher-spillet, men Geralt fra Rivia kan fortsatt ikke bestemme hvem han liker best: Yennefer fra Wengerberg eller Triss Merigold Men hvis du aldri har spilt The Witcher før, starter vi fra begynnelse. Hovedpersonens navn er Geralt av Rivia Geralt av Rivia er en hekser, en monsterjeger. Vi har erklært heltenes navn som konstanter. Nå kommer vi definitivt ikke til å skrive feil, og det er ikke nødvendig å skrive dem ut for hånd hver gang. Et annet pluss: hvis vi noen gang trenger å endre variabelens verdi på tvers av hele programmet, kan du gjøre det på ett sted, i stedet for å manuelt endre det på tvers av hele kodebasen. :)

Uforanderlige typer

Ettersom du har jobbet med Java, har du sannsynligvis allerede blitt vant til ideen om at programmerere har nesten full kontroll over tilstanden til alle objekter. Hvis du vil lage et Catobjekt, kan du. Hvis du vil gi det nytt navn, kan du. Hvis du vil endre alder eller noe annet, kan du. Men Java har flere datatyper som har en spesiell egenskap. De er uforanderlige . Hvis en klasse er uforanderlig, kan ikke tilstanden til objektene endres. Vil du ha noen eksempler? Det kan overraske deg, men den mest kjente uforanderlige klassen er String! Så vi kan virkelig ikke endre en strengs verdi? Vel, la oss prøve det:
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
}
Utgang: Jeg elsker Java Jeg elsker Java Etter at vi skrev
str1 = "I love Python";
strengobjektet "I love Java"endret seg ikke eller gikk noe sted. Den eksisterer heldigvis fortsatt og har nøyaktig samme tekst som før. Koden
str1 = "I love Python";
opprettet ganske enkelt et annet objekt, som str1 nå peker på. Men det ser ikke ut til at vi har noen effekt på "I love Java"-strengobjektet. Ok, la oss prøve noe annet! Klassen Stringer full av metoder, og noen av dem ser ut til å endre objektets tilstand! For eksempel er det en replace()metode. La oss endre ordet "Java" til "Python" i strengen vår!
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);
}
Utgang: Jeg elsker Java Jeg elsker Java Det fungerte ikke igjen! Kanskje erstatningsmetoden ikke fungerer? La oss prøve noe annet. For eksempel substring(). Den returnerer en delstreng basert på tegnindekser sendt som argumenter. La oss kutte av de første 10 tegnene i strengen vår:
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);
}
Utdata: Jeg elsker Java Jeg elsker Java Faste verdier i Java: endelig, konstanter og uforanderlige - 3 Ingenting har endret seg. Og det burde den ikke ha. Som vi sa tidligere, er strenger uforanderlige. Så, hva er det med alle metodene i klassen String? Tross alt kan de avkorte strenger, endre tegn og mer. Hva er vitsen hvis ingenting skjer? De kan faktisk gjøre disse tingene! Men de returnerer en ny streng hver gang. Det er meningsløst å skrive
str1.replace("Java", "Python");
fordi du ikke kan endre det opprinnelige objektet. Men hvis du skriver metodens resultat til en ny referansevariabel, vil du se forskjellen umiddelbart!
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);
}
Alle Stringmetoder fungerer på denne måten. Ingenting kan gjøres med objektet "I love Java". Du kan bare lage et nytt objekt og skrive: "<nytt objekt> = resultatet av å manipulere "I love Java" object ". Hvilke andre typer er uforanderlige? Noen som du definitivt må huske med en gang er alle innpakningsklassene for de primitive typene. Integer, Byte, Character, Short, Boolean, Long, Double, Float: alle disse klassene lager immutableobjekter (vi skal snakke om dem i kommende leksjoner). Dette inkluderer klasser som brukes til å lage store tall, for eksempel BigIntegerog BigDecimal. Vi dekket nylig unntak og berørte stabelsporet . Vel , gjett hva, java.lang.StackTraceElementobjekter er også uforanderlige. Dette gir mening: Hvis noen kunne endre dataene til stabelen vår, ville det gjøre det hele meningsløst. Se for deg at noen går gjennom stabelsporingen og endrer en OutOfMemoryError til en FileNotFoundException . Og så bruker du den stabelen for å finne årsaken til feilen. Men programmet bruker ikke engang filer. :) Så, de gjorde disse objektene uforanderlige, for sikkerhets skyld. Ok, så det er mer eller mindre fornuftig for StackTraceElement . Men hvorfor skulle noen trenge å gjøre strenger uforanderlige? Hvorfor skulle det være et problem å endre verdiene deres? Det ville nok til og med vært mer praktisk. :/ Det er flere grunner til dette. For det første sparer det minne. Uforanderlige strenger kan plasseres i strengbassenget, slik at strenger kan gjenbrukes i stedet for å lage nye. For det andre, for sikkerheten. For eksempel er brukernavn og passord strenger i nesten alle programmer. Å gjøre det mulig å endre dem kan føre til autorisasjonsproblemer. Det er andre grunner, men vår studie av Java har ikke dekket dem ennå, så vi kommer tilbake til dem senere.
Kommentarer
  • Populær
  • Ny
  • Gammel
Du må være pålogget for å legge igjen en kommentar
Denne siden har ingen kommentarer ennå