Bør vi lukke en Java-strøm?

1. Oversikt

Med introduksjonen av lambdauttrykk i Java 8 er det mulig å skrive kode på en mer kortfattet og funksjonell måte. Strømmer og funksjonelle grensesnitt er hjertet i denne revolusjonerende endringen i Java-plattformen.

I denne raske opplæringen lærer vi om vi eksplisitt skal lukke Java 8-strømmer ved å se på dem fra et ressursperspektiv.

2. Avslutte bekker

Java 8-strømmer implementerer Kan lukkes automatisk grensesnitt:

offentlig grensesnitt Stream utvider BaseStream {// utelatt} offentlig grensesnitt BaseStream utvider AutoCloseable {// utelatt}

Enkelt sagt, vi bør tenke på strømmer som ressurser som vi kan låne og returnere når vi er ferdige med dem. I motsetning til de fleste ressurser, trenger vi ikke alltid å lukke strømmer.

Dette kan høres kontraintuitivt ut i begynnelsen, så la oss se når vi skal og når vi ikke skal lukke Java 8-strømmer.

2.1. Samlinger, arrays og generatorer

Mesteparten av tiden skaper vi Strøm forekomster fra Java-samlinger, matriser eller generatorfunksjoner. For eksempel jobber vi her med en samling av String via Stream API:

Listefarger = List.of ("Red", "Blue", "Green") .stream () .filter (c -> c.length ()> 4) .map (String :: toUpperCase) .collect (Collectors. å liste opp());

Noen ganger genererer vi en endelig eller uendelig sekvensiell strøm:

Tilfeldig tilfeldig = ny Tilfeldig (); random.ints (). takeWhile (i -> i <1000) .forEach (System.out :: println);

I tillegg kan vi også bruke array-baserte strømmer:

Streng [] farger = {"Rød", "Blå", "Grønn"}; Arrays.stream (farger) .map (String :: toUpperCase) .toArray ()

Når vi arbeider med slike strømmer, bør vi ikke lukke dem eksplisitt. Den eneste verdifulle ressursen knyttet til disse strømningene er minne, og Garbage Collection (GC) tar seg av det automatisk.

2.2. IO Ressurser

Noen strømmer støttes imidlertid av IO-ressurser som filer eller stikkontakter. For eksempel Files.lines () metoden streamer alle linjene for den gitte filen:

Files.lines (Paths.get ("/ path / to / file")) .flatMap (line -> Arrays.stream (line.split (","))) // utelatt

Under panseret åpner denne metoden a FileChannel forekomst og lukker den deretter når strømmen stenges. Derfor, hvis vi glemmer å lukke strømmen, vil den underliggende kanalen forbli åpen, og da vil vi ende opp med en ressurslekkasje.

For å forhindre slike ressurslekkasjer, anbefales det sterkt å bruke prøv-med-ressurser idiom for å lukke IO-baserte strømmer:

prøv (Stream linjer = Files.lines (Paths.get ("/ path / to / file"))) {lines.flatMap (line -> Arrays.stream (line.split (","))) // utelatt}

På denne måten lukker kompilatoren kanalen automatisk. Nøkkelen til takeaway her er å lukke alle IO-baserte strømmer.

Vær oppmerksom på at å lukke en allerede lukket strøm vil kaste IllegalStateException.

3. Konklusjon

I denne korte opplæringen så vi forskjellene mellom enkle strømmer og IO-tunge. Vi lærte også hvordan disse forskjellene informerer om vår beslutning om å stenge Java 8-strømmer eller ikke.

Eksempelkoden er som vanlig tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found