Java >> Java tutorial >  >> Tag >> throw

Hvorfor tillader compileren kast, når metoden aldrig vil kaste undtagelsen

throws klausul er en del af metodens kontrakt. Det kræver, at den, der kalder metoden, opfører sig, som om den angivne undtagelse kan blive kastet af metoden (dvs. enten fange undtagelsen eller erklære deres egen throws klausul).

Det er muligt, at den oprindelige version af en metode ikke kaster undtagelsen angivet i throws klausul, men en fremtidig version kan kaste den uden at bryde API'en (dvs. enhver eksisterende kode, der kalder metoden, vil stadig bestå kompilering).

Det modsatte er også muligt. Hvis metoden brugt til at kaste undtagelsen angivet i throws klausul, men en fremtidig version af den kaster den ikke længere, du bør beholde throws klausul for ikke at bryde eksisterende kode, der bruger din metode.

Første eksempel:

Antag, at du har denne kode, som bruger methodB :

private static void methodA() {
    methodB(); // doesn't have throws IOException clause yet
}

Hvis du senere vil ændre methodB at kaste IOException , methodA vil stoppe med at bestå kompilering.

Andet eksempel:

Antag, at du har denne kode, som bruger methodB :

private static void methodA() {
    try {
        methodB(); // throws IOException
    }
    catch (IOException ex) {

    }
}

Hvis du fjerner throws klausul fra en fremtidig version af methodB , methodA vil ikke bestå kompileringen længere.

Dette eksempel er ikke særlig interessant, når methodA er private , fordi det kun kan bruges lokalt (inden for samme klasse, hvor det er nemt at ændre alle de metoder, der kalder det).

Men hvis det bliver public , du ved ikke, hvem der bruger (eller vil bruge) din metode, så du har ingen kontrol over al den kode, der kan gå i stykker som følge af tilføjelse eller fjernelse af throws klausul.

Og hvis det er en instansmetode, er der en anden grund til at tillade throws klausul, selvom du ikke kaster undtagelsen - metoden kan tilsidesættes, og den tilsidesættende metode kan kaste undtagelsen, selvom basisklasseimplementeringen ikke gør det.


Fordi signaturen definerer kontrakten for metoden. Selvom metoden ikke kaster en IOException nu, vil den måske gøre det i fremtiden, og du vil forberede dig på den mulighed.

Antag, at du bare leverer en dummy-implementering til metoden indtil videre, men du ved, at senere vil den faktiske implementering potentielt kaste en IOException. Hvis compileren forhindrede dig i at tilføje denne throws-klausul, ville du være tvunget til at omarbejde alle kald ( rekursivt) til denne metode, når du har angivet den faktiske implementering af metoden.


Java tag