Interviewvragen over Java-uitzonderingen (+ antwoorden)

Dit artikel maakt deel uit van een reeks: • Interviewvragen over Java Collections

• Vragen over het Java Type System-interview

• Vragen over Java Concurrency-sollicitatiegesprekken (+ antwoorden)

• Vragen over Java-klassenstructuur en initialisatie

• Java 8 sollicitatievragen (+ antwoorden)

• Geheugenbeheer in Java-interviewvragen (+ antwoorden)

• Java Generics sollicitatievragen (+ antwoorden)

• Vragen over Java Flow Control-interview (+ antwoorden)

• Java-uitzonderingen interviewvragen (+ antwoorden) (huidig ​​artikel) • Java-annotaties interviewvragen (+ antwoorden)

• Topvragen tijdens het Spring Framework-interview

1. Overzicht

Uitzonderingen zijn een essentieel onderwerp waarmee elke Java-ontwikkelaar vertrouwd moet zijn. Dit artikel geeft antwoord op enkele van de vragen die tijdens een interview kunnen opduiken.

2. Vragen

V1. Wat is een uitzondering?

Een uitzondering is een abnormale gebeurtenis die optreedt tijdens de uitvoering van een programma en die de normale stroom van de programma-instructies verstoort.

Q2. Wat is het doel van de trefwoorden voor gooien en gooien?

De gooit sleutelwoord wordt gebruikt om aan te geven dat een methode een uitzondering kan veroorzaken tijdens de uitvoering ervan. Het dwingt expliciete afhandeling van uitzonderingen af ​​bij het aanroepen van een methode:

public void simpleMethod () gooit uitzondering {// ...}

De werpen trefwoord stelt ons in staat om een ​​uitzonderingsobject te genereren om de normale stroom van het programma te onderbreken. Dit wordt meestal gebruikt als een programma niet aan een bepaalde voorwaarde voldoet:

if (task.isTooComplicated ()) {throw new TooComplicatedException ("De taak is te gecompliceerd"); }

Q3. Hoe kunt u met een uitzondering omgaan?

Door een probeer-vangst-eindelijk uitspraak:

probeer {// ...} catch (ExceptionType1 ex) {// ...} catch (ExceptionType2 ex) {// ...} eindelijk {// ...}

Het codeblok waarin een uitzondering kan voorkomen, is ingesloten in een proberen blok. Dit blok wordt ook wel "beschermde" of "bewaakte" code genoemd.

Als er een uitzondering optreedt, wordt het vangst blok dat overeenkomt met de uitzondering die wordt gegenereerd, wordt uitgevoerd, zo niet alles vangst blokken worden genegeerd.

De Tenslotte blok wordt altijd uitgevoerd na het proberen block exits, ongeacht of er een uitzondering in is gegooid of niet.

V4. Hoe kunt u meerdere uitzonderingen opvangen?

Er zijn drie manieren om meerdere uitzonderingen in een codeblok af te handelen.

De eerste is om een vangst blok dat alle uitzonderingstypen kan verwerken die worden gegenereerd:

probeer {// ...} catch (uitzondering ex) {// ...}

Houd er rekening mee dat de aanbevolen praktijk is om zo nauwkeurig mogelijk exception handlers te gebruiken.

Uitzonderingshandlers die te breed zijn, kunnen uw code gevoeliger maken voor fouten, uitzonderingen opvangen die niet waren voorzien en onverwacht gedrag in uw programma veroorzaken.

De tweede manier is het implementeren van meerdere catch-blokken:

probeer {// ...} catch (FileNotFoundException ex) {// ...} catch (EOFException ex) {// ...}

Merk op dat, als de uitzonderingen een overervingsrelatie hebben; het child-type moet eerst komen en het parent-type later. Als we dit niet doen, zal dit resulteren in een compilatiefout.

De derde is om een ​​multi-catch-blok te gebruiken:

probeer {// ...} catch (FileNotFoundException | EOFException ex) {// ...}

Deze functie, voor het eerst geïntroduceerd in Java 7; vermindert codeduplicatie en maakt het gemakkelijker te onderhouden.

V5. Wat is het verschil tussen een gecontroleerde en een niet-gecontroleerde uitzondering?

Een aangevinkte uitzondering moet worden afgehandeld binnen een proberen te vangen blokkeren of verklaard in een gooit clausule; terwijl een ongecontroleerde uitzondering niet hoeft te worden behandeld of aangegeven.

Gecontroleerde en niet-aangevinkte uitzonderingen worden ook wel respectievelijk compilatietijd- en runtime-uitzonderingen genoemd.

Alle uitzonderingen zijn aangevinkte uitzonderingen, behalve die aangegeven met Fout, RuntimeException, en hun subklassen.

V6. Wat is het verschil tussen een uitzondering en een fout?

Een uitzondering is een gebeurtenis die een toestand vertegenwoordigt waarvan herstel mogelijk is, terwijl een fout een externe situatie weergeeft waarvan meestal onmogelijk te herstellen is.

Alle fouten die door de JVM worden gegenereerd, zijn voorbeelden van Fout of een van zijn subklassen, de meest voorkomende omvatten, maar zijn niet beperkt tot:

  • Onvoldoende geheugen fout - wordt gegenereerd wanneer de JVM niet meer objecten kan toewijzen omdat er onvoldoende geheugen is en de garbage collector er niet meer beschikbaar kon maken
  • StackOverflowError - treedt op wanneer de stackruimte voor een thread op is, meestal omdat een applicatie te diep terugkeert
  • ExceptionInInitializerError - geeft aan dat er een onverwachte uitzondering is opgetreden tijdens de evaluatie van een statische initialisatieprogramma
  • NoClassDefFoundError - wordt gegenereerd wanneer de classloader de definitie van een klasse probeert te laden en deze niet kan vinden, meestal omdat het vereiste klasse bestanden zijn niet gevonden in het klassenpad
  • UnsupportedClassVersionError - treedt op wanneer de JVM probeert een klasse bestand en stelt vast dat de versie in het bestand niet wordt ondersteund, normaal omdat het bestand is gegenereerd met een nieuwere versie van Java

Hoewel een fout kan worden afgehandeld met een proberen verklaring, dit is geen aanbevolen praktijk, aangezien er geen garantie is dat het programma in staat zal zijn om iets betrouwbaars te doen nadat de fout is opgetreden.

V7. Welke uitzondering wordt geworpen bij het uitvoeren van het volgende codeblok?

Geheel getal [] [] ints = {{1, 2, 3}, {null}, {7, 8, 9}}; System.out.println ("value =" + ints [1] [1] .intValue ());

Het gooit een ArrayIndexOutOfBoundsException omdat we proberen toegang te krijgen tot een positie die groter is dan de lengte van de array.

V8. Wat is uitzonderingsketen?

Treedt op wanneer een uitzondering wordt gegenereerd als reactie op een andere uitzondering. Dit stelt ons in staat om de volledige geschiedenis van ons opgeworpen probleem te ontdekken:

probeer {task.readConfigFile (); } catch (FileNotFoundException ex) {throw new TaskException ("Kon taak niet uitvoeren", ex); }

V9. Wat is een Stacktrace en hoe verhoudt dit zich tot een uitzondering?

Een stacktracering biedt de namen van de klassen en methoden die werden aangeroepen, vanaf het begin van de toepassing tot het punt waarop een uitzondering optrad.

Het is een erg handig hulpmiddel voor het opsporen van fouten, omdat het ons in staat stelt om precies te bepalen waar de uitzondering in de toepassing is gegooid en de oorspronkelijke oorzaken die ertoe hebben geleid.

V10. Waarom zou u een uitzondering in een subklasse willen plaatsen?

Als het uitzonderingstype niet wordt vertegenwoordigd door degene die al op het Java-platform bestaan, of als u meer informatie aan de clientcode moet verstrekken om deze nauwkeuriger te behandelen, moet u een aangepaste uitzondering maken.

De beslissing of een aangepaste uitzondering moet worden aangevinkt of niet, hangt volledig af van de businesscase. Als vuistregel geldt echter; Als de code die uw uitzondering gebruikt, ervan kan worden verwacht dat deze hiervan herstelt, maak dan een aangevinkte uitzondering aan, maak het anders niet aangevinkt.

Je moet ook erven van de meest specifieke Uitzondering subklasse die nauw verband houdt met degene die u wilt gooien. Als er niet zo'n klasse is, kies dan Uitzondering als ouder.

V11. Wat zijn enkele voordelen van uitzonderingen?

Traditionele foutdetectie- en afhandelingstechnieken leiden er vaak toe dat spaghetticode moeilijk te onderhouden en moeilijk te lezen is. Uitzonderingen stellen ons echter in staat om de kernlogica van onze applicatie te scheiden van de details van wat te doen als er iets onverwachts gebeurt.

Ook, aangezien de JVM achterwaarts door de oproepstapel zoekt om methoden te vinden die geïnteresseerd zijn in het afhandelen van een bepaalde uitzondering; we krijgen de mogelijkheid om een ​​fout in de call-stack te verspreiden zonder extra code te schrijven.

Omdat alle uitzonderingen die in een programma worden gegenereerd, objecten zijn, kunnen ze ook worden gegroepeerd of gecategoriseerd op basis van de klassenhiërarchie. Dit stelt ons in staat om een ​​groep uitzonderingen in een enkele exception-handler af te vangen door de superklasse van de uitzondering op te geven in de vangst blok.

V12. Kun je een uitzondering in het lichaam van een Lambda-expressie werpen?

Wanneer u een standaard functionele interface gebruikt die al door Java wordt geleverd, kunt u alleen ongecontroleerde uitzonderingen gooien omdat standaard functionele interfaces geen "throws" -clausule hebben in methodehandtekeningen:

Lijst gehele getallen = Arrays.asList (3, 9, 7, 0, 10, 20); integers.forEach (i -> {if (i == 0) {throw new IllegalArgumentException ("Zero niet toegestaan");} System.out.println (Math.PI / i);});

Als u echter een aangepaste functionele interface gebruikt, is het mogelijk om aangevinkte uitzonderingen te gooien:

@FunctionalInterface openbare statische interface CheckedFunction {void apply (T t) gooit uitzondering; }
openbare ongeldige processTasks (Lijst taken, CheckedFunction gecontroleerdeFunctie) {voor (Taak taak: taken) {probeer {CheckedFunction.apply (taak); } catch (Exception e) {// ...}}} processTasks (taskList, t -> {// ... throw new Exception ("Er is iets gebeurd");});

V13. Wat zijn de regels die we moeten volgen bij het negeren van een methode die een uitzondering vormt?

Verschillende regels schrijven voor hoe uitzonderingen moeten worden verklaard in de context van overerving.

Als de bovenliggende class-methode geen uitzonderingen genereert, kan de child-class-methode geen aangevinkte uitzondering genereren, maar wel alle niet-aangevinkte uitzonderingen.

Hier is een voorbeeldcode om dit te demonstreren:

class Parent {void doSomething () {// ...}} class Child breidt Ouder {void doSomething () gooit IllegalArgumentException {// ...}}

Het volgende voorbeeld kan niet worden gecompileerd omdat de overriding-methode een aangevinkte uitzondering genereert die niet is gedeclareerd in de overschreven methode:

class Parent {void doSomething () {// ...}} class Child breidt Ouder {void doSomething () gooit IOException {// Compilatiefout}}

Wanneer de parent class-methode een of meer aangevinkte uitzonderingen genereert, kan de child class-methode elke ongecontroleerde uitzondering genereren; alle, geen of een deelverzameling van de gedeclareerde gecontroleerde uitzonderingen, en zelfs een groter aantal hiervan, zolang ze hetzelfde bereik of smaller zijn.

Hier is een voorbeeldcode die met succes de vorige regel volgt:

class Parent {void doSomething () gooit IOException, ParseException {// ...} void doSomethingElse () gooit IOException {// ...}} class Child breidt Ouder {void doSomething () gooit IOException {// ...} void doSomethingElse () gooit FileNotFoundException, EOFException {// ...}}

Merk op dat beide methoden de regel respecteren. De eerste gooit minder uitzonderingen dan de overschreven methode, en de tweede, ook al gooit hij meer; ze zijn smaller in omvang.

Als we echter proberen een aangevinkte uitzondering te genereren die de bovenliggende class-methode niet declareert, of als we er een met een bredere scope gooien; we krijgen een compilatiefout:

class Parent {void doSomething () gooit FileNotFoundException {// ...}} class Child breidt Parent {void doSomething () gooit IOException {// Compilatiefout}}

Wanneer de bovenliggende class-methode een throw-clausule heeft met een ongecontroleerde uitzondering, kan de child class-methode geen of een aantal ongecontroleerde uitzonderingen genereren, ook al zijn ze niet gerelateerd.

Hier is een voorbeeld dat de regel respecteert:

class Parent {void doSomething () gooit IllegalArgumentException {// ...}} class Child breidt Parent {void doSomething () gooit ArithmeticException, BufferOverflowException {// ...}}

V14. Zal de volgende code worden gecompileerd?

void doSomething () {// ... throw new RuntimeException (new Exception ("Chained Exception")); }

Ja. Bij het koppelen van uitzonderingen geeft de compiler alleen om de eerste in de keten en omdat het een ongecontroleerde uitzondering detecteert, hoeven we geen throw-clausule toe te voegen.

V15. Is er een manier om een ​​gecontroleerde uitzondering te maken van een methode die geen werpclausule heeft?

Ja. We kunnen profiteren van het wissen van het type dat door de compiler wordt uitgevoerd en het laten denken dat we een ongecontroleerde uitzondering werpen, terwijl in feite; we gooien een aangevinkte uitzondering:

openbare T sneakyThrow (Throwable ex) gooit T {throw (T) ex; } public void methodWithoutThrows () {this.sneakyThrow (nieuwe uitzondering ("Gecontroleerde uitzondering")); }

3. Conclusie

In dit artikel hebben we enkele van de vragen onderzocht die waarschijnlijk zullen voorkomen in technische interviews voor Java-ontwikkelaars, met betrekking tot uitzonderingen. Dit is geen uitputtende lijst en mag alleen worden behandeld als het begin van verder onderzoek.

Wij, bij Baeldung, wensen u veel succes bij de komende interviews.

De volgende » Vragen tijdens sollicitatiegesprek met Java-annotaties (+ antwoorden) « Eerdere Java Flow Control-sollicitatievragen (+ antwoorden)