JavaRush /Java Blog /Random-IT /Quindi finale...
Алексей
Livello 32

Quindi finale...

Pubblicato nel gruppo Random-IT
C'è una parola chiave in Java - final. Può essere applicato a classi, metodi, variabili (compresi gli argomenti del metodo). Quindi finale... - 1Per una classe, ciò significa che la classe non può avere sottoclassi, ad es. L'eredità è vietata. Ciò è utile quando si creano immutableoggetti (immutabili), ad esempio una classe Stringdichiarata come final.
public final class String{
}

class SubString extends String{ //Compilation error
}
Va inoltre notato che il modificatore non può essere applicato a classi astratte (con la parola chiave abstract), finalperché questi sono concetti che si escludono a vicenda. Per un metodo finalsignifica che non può essere sovrascritto nelle sottoclassi. Ciò è utile quando vogliamo che l'implementazione originale non venga sovrascritta.
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Compilation error
        System.out.println("MyReport");
    }
}
Per le variabili di tipo primitivo, ciò significa che una volta assegnato, il valore non può essere modificato. Per le variabili di riferimento, ciò significa che una volta assegnato un oggetto, il riferimento a quell'oggetto non può essere modificato. È importante! Il collegamento non può essere modificato, ma è possibile modificare lo stato dell'oggetto. Con Java 8 è apparso il concetto: effectively final. Si applica solo alle variabili (inclusi gli argomenti del metodo). Il punto è che nonostante l'ovvia assenza della parola chiave final, il valore della variabile non cambia dopo l'inizializzazione. In altre parole, è possibile sostituire una parola con tale variabile finalsenza che si verifichi un errore di compilazione. effectively finalLe variabili possono essere utilizzate all'interno di classi locali ( Local Inner Classes), classi anonime ( Anonymous Inner Classes), flussi (API Stream).
public void someMethod(){
    // In the example below, both a and b are effectively final, since the values ​​are set once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final because value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Compilation error
}
Adesso facciamo una piccola intervista. Dopotutto, l'obiettivo di seguire il corso JavaRush è diventare uno sviluppatore Java e ottenere un lavoro interessante e ben pagato. Quindi, cominciamo.
  1. Cosa puoi dire di un array quando viene dichiarato final?

  2. È noto che la classe Stringè immutable, la classe viene dichiarata final, il valore della stringa viene memorizzato in un array charcontrassegnato con la parola chiave final.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
È possibile sostituire il valore di un oggetto String(senza modificare il riferimento all'oggetto)? Queste sono vere domande da intervista. E come dimostra la pratica, molti rispondono in modo errato. Comprendere l'uso della parola chiave final, soprattutto per le variabili di riferimento, è molto importante. Mentre stai pensando, una breve digressione sul team JavaRush. Aggiungi un blocco nel tuo editor di testo che ti consenta di nascondere il contenuto e, quando fai clic su di esso, mostra questo contenuto. Risposte:
  1. Perché un array è un oggetto, il che finalsignifica che dopo aver assegnato un riferimento a un oggetto, non è più possibile modificarlo, ma è possibile modificare lo stato dell'oggetto.

    final int[] array = {1,2,3,4,5};
    array[0] = 9;	//ok, because change the contents of the array - {9,2,3,4,5}
    array = new int[5]; //compile error
  2. Si, puoi. La chiave è comprendere l'uso della parola pungente finalcon gli oggetti. Utilizza ReflectionAPI per sostituire il valore.

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 value field in the String class
        Field field = value.getClass().getDeclaredField("value");
        //Let's change it
        field.setAccessible(true);
        //Set new value
        field.set(value, "JavaRush".toCharArray());

        System.out.println(value);

        /* Вывод:
         * Old value
         * JavaRush
         */
    }
}
Tieni presente che se provassimo a modificare la variabile finale di un tipo primitivo in questo modo, non funzionerebbe nulla. Ti suggerisco di convincerti di questo: crea una classe Java, ad esempio, con final intun campo e prova a cambiarne il valore tramite la Reflection API. Buona fortuna a tutti!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION