CodeGym /Java blog /Tilfældig /Lad os tale om det endelige søgeord i Java
John Squirrels
Niveau
San Francisco

Lad os tale om det endelige søgeord i Java

Udgivet i gruppen
Java har dette nøgleord - final. Det kan anvendes på klasser, metoder, variabler (inklusive metodeparametre). For en klasse betyder det endelige nøgleord, at klassen ikke kan have underklasser, dvs. nedarvning er forbudt... Dette er nyttigt, når du opretter uforanderlige (uforanderlige) objekter. For eksempel er String-klassen erklæret som endelig.

    public final class String {
    }
    
    class SubString extends String { // Compilation error
    }
Jeg skal også bemærke, at den endelige modifikator ikke kan anvendes på abstrakte klasser (dem med søgeordet abstrakt), fordi disse er gensidigt udelukkende begreber. For en endelig metode betyder modifikatoren, at metoden ikke kan tilsidesættes i underklasser. Dette er nyttigt, når vi ønsker at forhindre ændring af den oprindelige implementering.

    public class SuperClass {
        public final void printReport() {
            System.out.println("Report");
        }
    }

    class SubClass extends SuperClass { 
        public void printReport() { //Compilation error
            System.out.println("MyReport");
        }
    }
For variabler af en primitiv type betyder det endelige nøgleord, at værdien, når den først er tildelt, ikke kan ændres. For referencevariable betyder det, at efter at et objekt er tildelt, kan du ikke ændre referencen til det objekt. Dette er vigtigt! Referencen kan ikke ændres, men objektets tilstand kan ændres. Java 8 introducerede et nyt koncept: faktisk endelig. Det gælder kun for variabler (inklusive metodeparametre). Den nederste linje er, at på trods af det klare fravær af det endelige søgeord, ændres variablens værdi ikke efter initialisering. Med andre ord kan det endelige nøgleord anvendes på en sådan variabel uden en kompileringsfejl. De endelige variabler kan effektivt bruges i lokale klasser (lokale indre klasser), anonyme klasser (anonyme indre klasser) og streams (Stream API).

        public void someMethod() {
            // In the example below, both a and b are effectively final, since they are assigned values only once:
            int a = 1;
            int b;
            if (a == 2) b = 3;
            else b = 4;
            // c is NOT effectively final since its value changes
            int c = 10;
            c++;
            
            Stream.of(1, 2).forEach(s-> System.out.println(s + a)); // OK
            Stream.of(1, 2).forEach(s-> System.out.println(s + c)); // Compilation error
        }
Lad os nu få et lille interview. Målet med at gennemføre CodeGym-kurset er jo at blive Java-udvikler og finde et interessant og godt betalt job. Så lad os begynde.
  1. Hvad kan vi sige om et array, der er erklæret endeligt?

  2. Vi ved, at String-klassen er uforanderlig: Klassen erklæres endelig. En strengværdi gemmes i et char-array, der er markeret med nøgleordet final.


public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

Kan vi erstatte et String-objekts værdi (uden at ændre referencen til objektet)? Det er rigtige interviewspørgsmål. Og praksis viser, at mange kandidater ikke svarer rigtigt på dem. At forstå, hvordan det endelige søgeord bruges, især for referencevariabler, er meget vigtigt. Mens du overvejer dette, vil jeg rette en lille anmodning til CodeGym-teamet. Giv venligst teksteditoren mulighed for at tilføje en blok, hvis indhold kan vises/skjules, når du klikker på den. Svar:
  1. Et array er et objekt, så det sidste nøgleord betyder, at når en reference til arrayet er tildelt, kan referencen ikke ændres. Når det er sagt, kan du ændre objektets tilstand.

    
            final int[] array = {1, 2, 3, 4, 5};
            array[0] = 9;	 // OK, because we're changing the contents of the array: {9, 2, 3, 4, 5}
            array = new int[5]; // Compilation error
    
  2. Ja vi kan. Det vigtigste er at forstå, hvad det tornede sidste nøgleord betyder, når det bruges sammen med objekter. Reflection API kan bruges til at erstatte værdier.


import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        // Get the String class's value field
        Field field = value.getClass().getDeclaredField("value");
        // Make it mutable
        field.setAccessible(true);
        // Set a new value
        field.set(value, "CodeGym".toCharArray());

        System.out.println(value);

        /* Output:
         * Old value
         * CodeGym
         */
    }
}
Bemærk venligst, at hvis vi havde forsøgt at ændre den endelige variabel af en primitiv type på denne måde, så ville der ikke være sket noget. Jeg foreslår, at du overbeviser dig selv: opret en Java-klasse, for eksempel med et sidste int-felt, og prøv at ændre dens værdi ved hjælp af Reflection API. Held og lykke til alle!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION