The Checker Framework - Pluggable Type Systems voor Java

1. Overzicht

Van de Java 8 vanaf release, is het mogelijk om programma's te compileren met behulp van de zogenaamde Inplugbare typesystemen - die strengere controles kunnen toepassen dan degene die door de compiler worden toegepast.

We hoeven alleen de annotaties van de verschillende te gebruiken Inplugbare typesystemen beschikbaar.

In dit korte artikel zullen we het verkennen het Checker Framework, met dank aan de Universiteit van Washington.

2. Maven

Om met het Checker Framework te gaan werken, moeten we het eerst toevoegen aan ons pom.xml:

 org.checkerframework checker-qual 2.3.2 org.checkerframework checker 2.3.2 org.checkerframework jdk8 2.3.2 

De laatste versie van de bibliotheken kan worden gecontroleerd op Maven Central.

De eerste twee afhankelijkheden bevatten de code van Het Checker Framework terwijl de laatste een aangepaste versie is van de Java 8 klassen, waarin alle typen correct zijn geannoteerd door de ontwikkelaars van Het Checker Framework.

We moeten dan het maven-compiler-plugin gebruiken Het Checker Framework als pluggable Typ Systeem:

 maven-compiler-plugin 3.6.1 1.8 1.8 10000 10000 org.checkerframework.checker.nullness.NullnessChecker org.checkerframework.checker.interning.InterningChecker org.checkerframework.checker.fenum.FenumChecker org.checkerframework.checker.rorStorcker.FormChecker. -Waarschuwt 

Het belangrijkste punt hier is de inhoud van de label. Hier hebben we alle checkers opgesomd die we tegen onze bronnen willen uitvoeren.

3. NullPointerExceptions vermijden

Het eerste scenario waarin Het Checker Framework kan ons helpen is het identificeren van het stuk codes waar een NullPoinerException zou kunnen ontstaan:

privé statische int countArgs (@NonNull String [] args) {return args.length; } openbare statische leegte hoofd (@Nullable String [] args) {System.out.println (countArgs (args)); }

In het bovenstaande voorbeeld hebben we verklaard met de @RTLnieuws annotatie dat het args argument van countArgs () moet niet nul zijn.

Ongeacht deze beperking, in hoofd(), roepen we de methode aan door een argument door te geven dat inderdaad null kan zijn, omdat het is geannoteerd met @Nullable.

Als we de code compileren, Het Checker Framework waarschuwt ons naar behoren dat er iets in onze code fout kan zijn:

[WAARSCHUWING] /checker-plugin/.../NonNullExample.java:[12,38] [argument.type.incompatible] incompatibele typen in argument. gevonden: null vereist: @Initialized @NonNull String @Initialized @NonNull []

4. Correct gebruik van constanten als opsommingen

Soms gebruiken we een reeks constanten omdat het items van een opsomming waren.

Stel dat we een reeks landen en planeten nodig hebben. We kunnen deze items dan annoteren met de @Fenum annotatie om alle constanten te groeperen die deel uitmaken van dezelfde 'nep'-opsomming:

static final @Fenum ("country") String ITALIË = "IT"; static final @Fenum ("country") String US = "US"; static final @Fenum ("country") String UNITED_KINGDOM = "UK"; static final @Fenum ("planet") String MARS = "Mars"; static final @Fenum ("planet") String EARTH = "Aarde"; static final @Fenum ("planet") String VENUS = "Venus";

Daarna, als we een methode schrijven die een String zou moeten accepteren die een "planeet" is, kunnen we het argument correct annoteren:

void greetPlanet (@Fenum ("planeet") String planeet) {System.out.println ("Hallo" + planeet); }

Per vergissing kunnen we een beroep doen greetPlanet () met een string die niet is gedefinieerd als een mogelijke waarde voor een planeet, zoals:

public static void main (String [] args) {obj.greetPlanets (VS); }

Het Checker Framework kan de fout herkennen:

[WAARSCHUWING] /checker-plugin/.../FakeNumExample.java:[29,26] [argument.type.incompatible] incompatibele typen in argument. gevonden: @Fenum ("land") Tekenreeks vereist: @Fenum ("planeet") Tekenreeks

5. Reguliere expressies

Laten we aannemen dat we een Draad variabele moet een reguliere expressie opslaan met ten minste één overeenkomende groep.

We kunnen profiteren het Checker Framework en verklaar zo'n variabele als dat:

@Regex (1) privé statische string FIND_NUMBERS = "\ d *";

Dit is duidelijk een mogelijke fout omdat de reguliere expressie die we hebben toegewezen FIND_NUMBERS heeft geen overeenkomende groep.

Inderdaad, het Checker Framework zal ons ijverig informeren over onze fout tijdens het compileren:

[WAARSCHUWING] /checker-plugin/.../RegexExample.java:[7,51] [toewijzing.type.incompatibel] incompatibele typen in toewijzing. gevonden: @Regex String vereist: @Regex (1) String

6. Conclusie

Het Checker Framework is een handig hulpmiddel voor ontwikkelaars die verder willen gaan dan de standaard compiler en de juistheid van hun code willen verbeteren.

Het is in staat om tijdens het compileren verschillende typische fouten te detecteren die gewoonlijk alleen tijdens runtime kunnen worden gedetecteerd of zelfs de compilatie te stoppen door een compilatiefout te veroorzaken.

Er zijn veel meer standaardcontroles dan wat we in dit artikel hebben besproken; bekijk de beschikbare cheques in Het Checker Framework officiële handleiding hier, of schrijf zelfs uw eigen handleiding.

Zoals altijd is de broncode voor deze tutorial, met wat meer voorbeelden, te vinden op GitHub.