CodeGym /Java Blog /Willekeurig /Laten we het hebben over het laatste zoekwoord in Java
John Squirrels
Niveau 41
San Francisco

Laten we het hebben over het laatste zoekwoord in Java

Gepubliceerd in de groep Willekeurig
Java heeft dit sleutelwoord - definitief. Het kan worden toegepast op klassen, methoden, variabelen (inclusief methodeparameters). Voor een klasse betekent het laatste trefwoord dat de klasse geen subklassen kan hebben, dwz overerving is verboden... Dit is handig bij het maken van onveranderlijke (onveranderlijke) objecten. De klasse String wordt bijvoorbeeld als definitief gedeclareerd.

    public final class String {
    }
    
    class SubString extends String { // Compilation error
    }
Ik moet ook opmerken dat de laatste modifier niet kan worden toegepast op abstracte klassen (die met het trefwoord abstract), omdat dit elkaar wederzijds uitsluitende concepten zijn. Voor een laatste methode betekent de modifier dat de methode niet kan worden overschreven in subklassen. Dit is handig als we de wijziging van de oorspronkelijke implementatie willen voorkomen.

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

    class SubClass extends SuperClass { 
        public void printReport() { //Compilation error
            System.out.println("MyReport");
        }
    }
Voor variabelen van een primitief type betekent het laatste trefwoord dat de waarde, eenmaal toegewezen, niet kan worden gewijzigd. Voor referentievariabelen betekent dit dat nadat een object is toegewezen, u de verwijzing naar dat object niet meer kunt wijzigen. Dit is belangrijk! De referentie kan niet worden gewijzigd, maar de status van het object kan wel worden gewijzigd. Java 8 introduceerde een nieuw concept: effectief definitief. Het is alleen van toepassing op variabelen (inclusief methodeparameters). Het komt erop neer dat ondanks de duidelijke afwezigheid van het laatste trefwoord, de waarde van de variabele niet verandert na initialisatie. Met andere woorden, het laatste trefwoord kan zonder compilatiefout op zo'n variabele worden toegepast. Uiteindelijke variabelen kunnen effectief worden gebruikt binnen lokale klassen (lokale binnenklassen), anonieme klassen (anonieme binnenklassen) en 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
        }
Laten we nu een klein interview houden. Het doel van het voltooien van de CodeGym-cursus is immers om Java-ontwikkelaar te worden en een interessante en goedbetaalde baan te vinden. Laten we beginnen.
  1. Wat kunnen we zeggen over een array die definitief wordt verklaard?

  2. We weten dat de klasse String onveranderlijk is: de klasse wordt definitief verklaard. Een tekenreekswaarde wordt opgeslagen in een char-array die is gemarkeerd met het trefwoord final.


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

Kunnen we de waarde van een String-object vervangen (zonder de verwijzing naar het object te wijzigen)? Dit zijn echte sollicitatievragen. En de praktijk leert dat veel kandidaten deze niet goed beantwoorden. Het is erg belangrijk om te begrijpen hoe het laatste trefwoord wordt gebruikt, vooral voor referentievariabelen. Terwijl je hierover nadenkt, zal ik een klein verzoek doen aan het CodeGym-team. Geef de teksteditor de mogelijkheid om een ​​blok toe te voegen waarvan de inhoud kan worden getoond/verborgen wanneer u erop klikt. antwoorden:
  1. Een array is een object, dus het laatste sleutelwoord betekent dat zodra een verwijzing naar de array is toegewezen, de verwijzing niet kan worden gewijzigd. Dat gezegd hebbende, kunt u de status van het object wijzigen.

    
            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 dat kunnen we. Het belangrijkste is om te begrijpen wat het netelige laatste trefwoord betekent wanneer het met objecten wordt gebruikt. De Reflection API kan worden gebruikt om waarden te vervangen.


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
         */
    }
}
Houd er rekening mee dat als we hadden geprobeerd de laatste variabele van een primitief type op deze manier te veranderen, er niets zou zijn gebeurd. Ik stel voor dat je jezelf overtuigt: maak bijvoorbeeld een Java-klasse met een laatste int-veld en probeer de waarde ervan te wijzigen met behulp van de Reflection API. Succes allemaal!
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION