Java >> Java tutorial >  >> Tag >> final

Forskelle mellem Final, Final og Finalize i Java

1. Oversigt

I dette selvstudie vil vi tage en oversigt over tre Java-nøgleord: endelig, endelig  og afslut.

Selvom disse søgeord ligner hinanden, har de hver deres betydning i Java. Vi vil lære formålet med hver af dem og se nogle eksempler gennem en smule kode.

2. endelig Søgeord

Lad os først tage et kig på finalen søgeord, hvor det skal bruges og hvorfor. Vi kan anvende finalen nøgleord til klasse, metode, felt, variabel og metodeparametererklæringer.

Det har dog ikke den samme effekt på hver af dem :

  • Gør en klasse til finale betyder, at det ikke vil være muligt at udvide denne klasse
  • Tilføjer endelig til en metode betyder, at det ikke vil være muligt at tilsidesætte denne metode
  • Til sidst sætter du final foran et felt, en variabel eller en parameter betyder, at når referencen er blevet tildelt, kan den ikke ændres (hvis referencen er til et objekt, der kan ændres, kan dens interne tilstand ændre sig, selvom den er endelig)

En detaljeret artikel om den endelige søgeord kan findes her.

Lad os se, hvordan finalen søgeord fungerer gennem nogle eksempler.

2.1. endelig Felter, parametre og variabler

Lad os oprette en forælder klasse med to int  felter, en endelig en, og en almindelig ikke-finale:

public class Parent {

    int field1 = 1;
    final int field2 = 2;

    Parent() {
        field1 = 2; // OK
        field2 = 3; // Compilation error
    }

}

Som vi kan se, forbyder compileren os at tildele en ny værdi til felt2 .

Lad os nu tilføje en metode med et regulært og et sidste argument:

    void method1(int arg1, final int arg2) {
        arg1 = 2; // OK
        arg2 = 3; // Compilation error
    }

På samme måde som felter er det ikke muligt at tildele noget til arg2 da det er erklæret endeligt.

Vi kan nu tilføje en anden metode for at illustrere, hvordan dette virker med lokale variabler:

    void method2() {
        final int localVar = 2; // OK
        localVar = 3; // Compilation error
    }

Der sker ikke noget overraskende, compileren lader os ikke tildele en ny værdi til localVar efter dens første tildeling.

2.2. endelig Metode

Antag nu, at vi laver metode2 final og opret en underklasse af Forælder , lad os sige Barn , hvor vi forsøger at tilsidesætte begge dets superklasse metoder:

public class Child extends Parent {

    @Override
    void method1(int arg1, int arg2) {
        // OK
    }
    
    @Override
    final void method2() {
        // Compilation error
    }

}

Som vi kan se, er der ikke noget problem med at tilsidesætte method1() , men vi får en kompileringsfejl, når vi forsøger at tilsidesætte method2() .

2.3. endelig Klasse

Og endelig, lad os lave Barnet klasse finalen og prøv at oprette en underklasse af den, Barnebarn :

public final class Child extends Parent { 
    // ... 
}
public class GrandChild extends Child {
    // Compilation error
}

Endnu en gang klager compileren. Barnet klasse er endelig og derfor umulig at forlænge.

3. endelig Bloker

Den endelig blok er en valgfri blok til brug med en try/catch udmelding. I denne blok inkluderer vi kode, der skal udføres efter try/catch  struktur, uanset om der er smidt en undtagelse eller ej .

Det er endda muligt at bruge det med forsøg blokere uden nogen fangst blok, forudsat at vi inkluderer en endelig blok. Koden vil derefter blive eksekveret efter forsøget eller efter en undtagelse er kastet.

Vi har en dybdegående artikel om håndtering af undtagelser i Java her.

Lad os nu demonstrere en endelig blok i et kort eksempel. Vi opretter en dummy main() metode med en try/catch/finally struktur:

public static void main(String args[]) {
    try {
        System.out.println("Execute try block");
        throw new Exception();
    } catch (Exception e) {
        System.out.println("Execute catch block");
    } finally {
        System.out.println("Execute finally block");
    }
}

Hvis vi kører denne kode, udsender den følgende:

Execute try block
Execute catch block
Execute finally block

Lad os nu ændre metoden ved at fjerne catch-blokken (og tilføje kast Undtagelse til underskriften):

public static void main(String args[]) throws Exception {
    try {
        System.out.println("Execute try block");
        throw new Exception();
    } finally {
        System.out.println("Execute finally block");
    }
}

Outputtet er nu:

Execute try block
Execute finally block

Hvis vi nu fjerner throw new Exception() instruktion, kan vi observere, at output forbliver det samme. Vores endelig blokudførelse forekommer hver gang.

4. afslut Metode

Og til sidst, færdiggørelsen metode er en beskyttet metode, defineret i Object-klassen. Det kaldes af skraldesamleren på objekter, der ikke længere refereres til, og som er blevet udvalgt til affaldsindsamling .

Som enhver anden ikke-endelig metode kan vi tilsidesætte denne metode for at definere den adfærd et objekt skal have, når det indsamles af skraldsamleren .

Igen en detaljeret artikel, der dækker det afslutte metode kan findes her.

Lad os se et eksempel på, hvordan det virker. Vi bruger System.gc() for at foreslå JVM for at udløse affaldsindsamling :

    @Override
    protected void finalize() throws Throwable {
        System.out.println("Execute finalize method");
        super.finalize();
    }
    public static void main(String[] args) throws Exception {
        FinalizeObject object = new FinalizeObject();
        object = null;
        System.gc();
        Thread.sleep(1000);
    }

I dette eksempel tilsidesætter vi finalize() metode i vores objekt og opret en main() metode, som instansierer vores objekt og straks dropper referencen ved at sætte den oprettede variabel til null .

Derefter kalder vi System.gc() for at køre skraldsamleren (i det mindste forventer vi, at den kører) og vente et sekund (bare for at sikre, at JVM lukker ikke ned før skraldsamler har chancen for at kalde finalize() metode).

Outputtet af denne kodeudførelse skal være:

Execute finalize method

Bemærk, at det anses for dårlig praksis at tilsidesætte finalize() metode, da dens udførelse afhænger af affaldsopsamling som er i hånden på JVM . Derudover er denne metode blevet udfaset siden Java 9.

5. Konklusion

I denne artikel har vi kort diskuteret forskellene mellem de tre Java-søgeord: endelig, endelig og afslut .

Den fulde kode for artiklen kan findes på GitHub.


Java tag