CodeGym /Java blogg /Slumpmässig /Låt oss prata om sista nyckelordet i Java
John Squirrels
Nivå
San Francisco

Låt oss prata om sista nyckelordet i Java

Publicerad i gruppen
Java har detta nyckelord - final. Det kan appliceras på klasser, metoder, variabler (inklusive metodparametrar). För en klass betyder det sista nyckelordet att klassen inte kan ha underklasser, dvs arv är förbjudet... Detta är användbart när man skapar oföränderliga (oföränderliga) objekt. Till exempel deklareras String-klassen som final.

    public final class String {
    }
    
    class SubString extends String { // Compilation error
    }
Jag bör också notera att den slutliga modifieraren inte kan tillämpas på abstrakta klasser (de med nyckelordet abstrakt), eftersom dessa är ömsesidigt uteslutande begrepp. För en slutlig metod innebär modifieraren att metoden inte kan åsidosättas i underklasser. Detta är användbart när vi vill förhindra ändring av den ursprungliga implementeringen.

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

    class SubClass extends SuperClass { 
        public void printReport() { //Compilation error
            System.out.println("MyReport");
        }
    }
För variabler av primitiv typ innebär det sista nyckelordet att värdet, när det väl har tilldelats, inte kan ändras. För referensvariabler betyder det att efter att ett objekt har tilldelats kan du inte ändra referensen till det objektet. Det här är viktigt! Referensen kan inte ändras, men objektets tillstånd kan ändras. Java 8 introducerade ett nytt koncept: faktiskt final. Den gäller endast för variabler (inklusive metodparametrar). Summan av kardemumman är att trots den tydliga frånvaron av det slutliga nyckelordet ändras inte variabelns värde efter initialisering. Med andra ord kan det sista nyckelordet appliceras på en sådan variabel utan ett kompileringsfel. Slutliga variabler kan effektivt användas i lokala klasser (lokala inre klasser), anonyma klasser (anonyma inre klasser) och strömmar (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
        }
Nu ska vi ta en liten intervju. Målet med att gå CodeGym-kursen är trots allt att bli Javautvecklare och hitta ett intressant och välbetalt jobb. Så, låt oss börja.
  1. Vad kan vi säga om en array som förklaras slutgiltig?

  2. Vi vet att String-klassen är oföränderlig: klassen förklaras final. Ett strängvärde lagras i en char-array som är markerad med nyckelordet 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 ersätta ett String-objekts värde (utan att ändra referensen till objektet)? Det här är riktiga intervjufrågor. Och praxis visar att många kandidater inte svarar rätt på dem. Att förstå hur det slutliga nyckelordet används, särskilt för referensvariabler, är mycket viktigt. När du funderar på detta kommer jag att göra en liten förfrågan till CodeGym-teamet. Ge textredigeraren möjligheten att lägga till ett block vars innehåll kan visas/gömmas när du klickar på det. Svar:
  1. En array är ett objekt, så det sista nyckelordet betyder att när en referens till arrayen har tilldelats kan referensen inte ändras. Som sagt, du kan ändra objektets tillstånd.

    
            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 det kan vi. Det viktigaste är att förstå vad det svåra sista nyckelordet betyder när det används med objekt. Reflection API kan användas för att ersätta värden.


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
         */
    }
}
Observera att om vi hade försökt ändra den slutliga variabeln för en primitiv typ på detta sätt, så hade ingenting hänt. Jag föreslår att du övertygar dig själv: skapa en Java-klass, till exempel, med ett sista int-fält och försök ändra dess värde med hjälp av Reflection API. Lycka till allihopa!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION