Programmering

Verdien av String.valueOf

De fleste Java-utviklere har sannsynligvis fått mett NullPointerException. De fleste av oss har lært verdien av å gjøre visse ting for å redusere våre "muligheter" for å møte NullPointerException. Det er faktisk en Wiki-side dedikert til å forhindre eller redusere NullPointerExceptions.

Flere mennesker har argumentert for ytterligere språkstøtte for forbedret og enklere håndtering av potensiell null. Disse inkluderer Java SE 7-forslag, Optimized Null Check og Kinga Dobolyis avhandling Changing Java’s Semantics for Handling Null Pointer Exceptions.

Blant de mange tingene vi allerede kan gjøre ganske enkelt for å redusere møtene med NullPointerException, er det spesielt enkelt å bruke String.valueOf (Object) når det er aktuelt. De String.valueOf (Object) metoden, som den Javadoc-genererte dokumentasjonen sier, returnerer "null" hvis det sendte objektet er null og returnerer resultatene på innleveringen Gjenstand's toString () -anrop hvis den sendte inn Gjenstand er ikke null. Med andre ord, String.valueOf (String) kontrollerer null for deg.

Bruken av String.valueOf (Object) er spesielt nyttig ved implementering toString metoder på tilpassede klasser. Fordi de fleste toString implementeringer gir klassens datamedlemmer i strengformat, String.valueOf (Object) er en naturlig passform. Alle Java-objekter basert på klasser som utvider Object gir a toString () implementering selv om det bare er foreldrenes (eller til og med Gjenstand's) implementering av toString (). Imidlertid hvis en medlemsklasse implementerer toString men selve medlemmet er null snarere enn en forekomst av klassen, så er toString () gjør ikke noe bra (og fører faktisk til en NullPointerException når du blir kalt).

Dette demonstreres med følgende eksempelkode.

StringHandlingExample.java

pakke dustin. eksempler; importere java.io.IOException; importere java.io.OutputStream; importere java.util.logging.Logger; / ** * Eksempelklasse som viser bruk av strengrepresentasjoner tilgjengelig via * implisitt streng, toString () og String.valueOf (). * / public class StringHandlingExample {private static final String NEW_LINE = System.getProperty ("line.separator"); / ** Bruke java.util.logging. * / private static Logger LOGGER = Logger.getLogger (StringHandlingExample.class.getName ()); / ** * Hovedfunksjon for å kjøre tester / demonstrasjoner. * * @param argumenter Kommandolinje argumenter; ingen forventet. * / public static void main (final String [] argumenter) {printHeader ("Stringrepresentasjon av direkte strenger", System.out); endelig Personnavn personnavn = nytt Personnavn ("Flintstone", null); System.out.println ("Persons navn [DIRECT]:" + personnavn); System.out.println ("Persons navn [TOSTRING]:" + personnavn.toString ()); System.out.println ("Persons navn [STRING.VALUEOF]:" + String.valueOf (personnavn)); printBlankLine (System.out); printHeader ("Stringrepresentasjon av ikke-null kompleks objekt", System.out); endelig Person personOne = ny person (personnavn); System.out.println ("Person One [DIRECT]:" + personOne); System.out.println ("Person One [TOSTRING]:" + personOne.toString ()); System.out.println ("Person One [STRING.VALUEOF]:" + String.valueOf (personOne)); printBlankLine (System.out); printHeader ("Stringrepresentasjon av null kompleks objekt", System.out); endelig person personTo = ny person (null); System.out.println ("Person Two [DIRECT]:" + personTwo); System.out.println ("Person Two [TOSTRING]:" + personTwo.toString ()); System.out.println ("Person Two [STRING.VALUEOF]:" + String.valueOf (personTwo)); printBlankLine (System.out); } public static void printHeader (final String message, final OutputStream out) {final String headerSeparator = "================================= ======================================== "; prøv {out.write ((headerSeparator + NEW_LINE + melding + NEW_LINE) .getBytes ()); out.write ((headerSeparator + NEW_LINE) .getBytes ()); } fange (IOException ioEx) {System.out.println (headerSeparator); System.out.println (melding); System.out.println (headerSeparator); LOGGER.warning ("Kunne ikke skrive topptekstinformasjon til gitt OutputStream."); }} offentlig statisk ugyldig printBlankLine (endelig OutputStream ut) {prøv {out.write (NEW_LINE.getBytes ()); } fange (IOException ioEx) {System.out.println (NEW_LINE); LOGGER.warning ("Kunne ikke skrive tom linje til gitt OutputStream."); }} / ** * Klasse som du skal ringe tilString. * / privat statisk klasse Personnavn {privat streng etternavn; privat streng fornavn; public PersonName (final String newLastName, final String newFirstName) {lastName = newLastName; firstName = newFirstName; } / ** * Gi strengrepresentasjon av meg. * * @return My String representasjon. * / @Override public String toString () {return firstName + "" + lastName; }} privat statisk klasse Person {private PersonName name; offentlig person (endelig personnavn nytt navn) {navn = nytt navn; } / ** * Gi strengrepresentasjon av meg. * * @return My String representasjon. * / public String toString () {// Ikke bruk - fører til kompilatortidsfeil (inkompatible typer) // returnavn; // Ikke bruk - kan føre til kjøretidsfeil (NullPointerException) // return name.toString (); // Alt er bra retur String.valueOf (navn); }}} 

Ovennevnte kode kan brukes til å demonstrere bygging av en toString metode på et komplekst objekt og hvordan det oppfører seg når det kalles av en eierklasse. Metoden som er mest interessant er nederst i koden vist ovenfor. To returverdier kommenteres på grunn av problemer knyttet til dem. Det siste eksemplet, ved hjelp av String.valueOf (Object) blir IKKE kommentert fordi den fungerer best hver gang den kjøres, uansett om den er kompleks eller ikke Personnavn objektet er null. De neste tre bildene viser utdataene for hver av disse presentasjonene av personobjektenes strengrepresentasjoner.

Strengverdi fra komplekst objekt - Kompileringstidsfeil

Strengverdi fra komplekst objekt til String () - Potensiell kjøretid NullPointerException

Strengverdi fra komplekst objekt String.valueOf () - Nulls håndtert elegant

Ved hjelp av String.valueOf (Object) i toString () implementeringer kan være spesielt fordelaktige fordi vi ofte bruker toString () metoden når vi feilsøker og det siste vi trenger i slike tilfeller, er et annet unntak mens vi prøver å se den nåværende tilstanden til dataene våre. Man kan selvfølgelig også implementere toString () metoder med egne sjekker for null eller, enda bedre, man kan bruke noe som ToStringBuilder. Tilgjengeligheten av String.valueOf (Object) er absolutt noe som er verdt å huske på og er noe jeg finner meg selv i å bruke ganske ofte. Mange av oss har funnet færre kodelinjer for å være mer tydelige og String.valueOf (Object) kan være mye mer tydelig enn å eksplisitt sjekke et objekt for null før det påberopes det toString () gjennomføring.

Til slutt gir strengklassen mange overbelastede verdi-av-metoder. I tillegg til versjonen som var fokus for dette blogginnlegget (godtar et objekt), godtar de andre overbelastede versjonene av valueOf primitive datatyper og matriser med primitive datatyper.

Konklusjon

Uansett hva fremtiden bringer når det gjelder forbedret nullhåndtering i Java, er det mange taktikker vi kan ta i dag for å redusere de uønskede (noen ganger vil vi faktisk at de skal kastes!) Forekomster av NullPointerException. En av disse er å bruke String.valueOf (Object) når det passer seg.

Tilleggsressurser

  • String.valueOf eller Integer.toString ()?
  • Eksplisitt versus Implisitt Call of toString
  • Verdien av en streng med String.valueOf () -metoden
  • Konverter nummer til streng

Denne historien, "The Value of String.valueOf" ble opprinnelig utgitt av JavaWorld.

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