Programmēšana

Java toString () apsvērumi

Pat sākuma Java izstrādātāji zina par Object.toString () metodes lietderību, kas ir pieejama visiem Java klases gadījumiem un kuru var ignorēt, lai sniegtu noderīgu informāciju par jebkuru konkrētu Java klases gadījumu. Diemžēl pat pieredzējuši Java izstrādātāji dažkārt dažādu iemeslu dēļ pilnībā neizmanto šo spēcīgo Java funkciju. Šajā emuāra ziņā es aplūkoju pazemīgo Java toString () un aprakstiet vienkāršus soļus, ko var veikt, lai uzlabotu toString ().

Skaidri ieviest (ignorēt) toString ()

Varbūt vissvarīgākais apsvērums, kas saistīts ar maksimālās vērtības sasniegšanu no toString () ir nodrošināt to ieviešanu. Lai gan visu Java klases hierarhiju sakne Object nodrošina toString () ieviešanu, kas ir pieejama visām Java klasēm, šīs metodes noklusējuma darbība gandrīz nekad nav noderīga. Javadoc for Object.toString () paskaidro, kas pēc noklusējuma tiek nodrošināts toString (), ja klasei nav paredzēta pielāgota versija:

Metode toString klases objektam atgriež virkni, kas sastāv no tās klases nosaukuma, kuras objekts ir eksemplārs, at-sign rakstzīmes “@” un objekta hash koda neparakstīta heksadecimāla attēla. Citiem vārdiem sakot, šī metode atgriež virkni, kas vienāda ar vērtību:getClass (). getName () + '@' + Integer.toHexString (hashCode ())

Ir grūti nākt klajā ar situāciju, kurā noder klases nosaukums un objekta hash koda heksadecimālais attēlojums, atdalīts ar @ zīmi. Gandrīz visos gadījumos ir daudz noderīgāk nodrošināt pielāgotu, skaidru

toString ()

ieviešana klasē, lai ignorētu šo noklusējuma versiju.

Javadoc for Object.toString () arī stāsta mums, ko a toString () ieviešanai parasti vajadzētu būt saistītai, un tā arī sniedz to pašu ieteikumu, kuru es šeit sniedzu: ignorēt toString ():

KopumātoString method atgriež virkni, kas "tekstuāli attēlo" šo objektu. Rezultātā jābūt īsai, bet informatīvai pārstāvībai, kuru personai ir viegli lasīt. Visām apakšklasēm ieteicams ignorēt šo metodi.

Ikreiz, kad es rakstu jaunu klasi, ir vairākas metodes, kuras es apsveru iespēju pievienot kā daļu no jaunās klases radīšanas. Tie ietver

hashCode ()

un

vienāds (objekts)

ja nepieciešams. Tomēr, pēc manas pieredzes un, manuprāt, īstenojot skaidri

toString ()

vienmēr ir piemērots.

Ja Javadoc ieteikums, ka "visas apakšklases ignorē šo metodi", nav pietiekams (tad es nedomāju, ka arī mans ieteikums ir), lai Java izstrādātājam attaisnotu skaidra teksta nozīmi un vērtību toString () metodi, tad es iesaku pārskatīt Džoša Bloka efektīvo Java vienumu "Vienmēr ignorēt toString", lai iegūtu papildu informāciju par ieviešanas nozīmi toString (). Es uzskatu, ka visiem Java izstrādātājiem vajadzētu piederēt to kopijai Efektīva Java, bet par laimi nodaļa ar šo vienumu ieslēgta toString () ir pieejama tiem, kuriem kopija nepieder: Metodes, kas kopīgas visiem objektiem.

Uzturēt / atjaunināt toString ()

Nepatīkami ir tieši vai netieši saukt objektu toString () žurnāla paziņojumā vai citā diagnostikas rīkā un atgrieziet noklusējuma klases nosaukumu un objekta heksidecimālo hash kodu, nevis kaut ko noderīgāku un lasāmāku. Tas ir gandrīz tikpat nepatīkami, ja ir nepilnīgs toString () ieviešana, kas neietver nozīmīgus objekta pašreizējo raksturlielumu un stāvokļa gabalus. Es cenšos būt pietiekami disciplinēts un radīt un ievērot ieradumu vienmēr pārskatīt toString () ieviešana kopā ar programmas pārskatīšanu vienāds (objekts) un hashCode () jebkuras klases, kurā strādāju, ieviešana man ir jauna vai ikreiz, kad pievienoju vai mainu klases atribūtus.

Tikai fakti (bet visi / lielākā daļa no tiem!)

Nodaļā Efektīva Java iepriekš minēts, Blohs raksta: "Kad tas ir praktiski, metodei toString vajadzētu atgriezt visu interesanto informāciju, kas atrodas objektā." Tas var būt sāpīgi un nogurdinoši pievienot visus atribūtus smagās klases atribūtus toString ieviešanai, taču vērtība tiem, kas mēģina atkļūdot un diagnosticēt ar šo klasi saistītos jautājumus, būs vērts ieguldīt. Es parasti cenšos, lai visi manas instances nozīmīgie atribūti, kas nav nulle, būtu ģenerētajā virknes attēlojumā (un dažreiz ietver to, ka daži atribūti ir nulle). Atribūtiem parasti pievienoju arī minimālu identifikācijas tekstu. Tā daudzējādā ziņā ir vairāk māksla nekā zinātne, taču es cenšos iekļaut pietiekami daudz teksta, lai atšķirtos atribūti, nenosakot nākamos izstrādātājus ar pārāk detalizētu informāciju. Man vissvarīgākais ir iegūt atribūtu vērtības un kāda veida identifikācijas atslēgu.

Ziniet savu auditoriju

Viena no visbiežāk pieļautajām kļūdām, ko esmu redzējis Java izstrādātājiem, kas nav iesācēji, attiecībā uz toString () ir aizmirst kas un kas toString () parasti ir paredzēts. Kopumā toString () ir diagnostikas un atkļūdošanas rīks, kas ļauj ērti reģistrēt informāciju par konkrētu gadījumu noteiktā laikā, lai vēlāk atkļūdotu un diagnosticētu. Parasti ir kļūda, ja lietotāja saskarnēs tiek parādīti virknes attēlojumi, ko ģenerējis toString () vai pieņemt loģiskus lēmumus, pamatojoties uz a toString () pārstāvība (faktiski loģisku lēmumu pieņemšana par jebkuru virkni ir trausla!). Esmu redzējis labi domājošus izstrādātājus toString () atgriezt XML formātu lietošanai citā XML draudzīgā koda aspektā. Vēl viena būtiska kļūda ir piespiest klientus analizēt atgriezto Stringu toString () lai sistemātiski piekļūtu datu dalībniekiem. Iespējams, labāk ir nodrošināt publisku getter / accessor metodi, nevis paļauties uz toString () nekad nemainās. Visas šīs ir kļūdas, jo šīs pieejas aizmirst a nodomu toString () ieviešana. Tas ir īpaši mānīgi, ja izstrādātājs noņem svarīgas īpašības no toString () metodi (skat. pēdējo vienumu), lai tā lietotāja saskarnē izskatītos labāk.

man patīk toString () ieviešanu, lai būtu visas atbilstošās detaļas un nodrošinātu minimālu formatējumu, lai padarītu šīs detaļas patīkamākas. Šajā formatējumā var būt saprātīgi atlasītas jaunas rindiņu rakstzīmes [System.getProperty ("line.seperator");] un cilnēm, koliem, semikoliem utt. Es neieguldu tikpat daudz laika, cik es ieguldītu programmatūras galalietotājam uzrādītajā rezultātā, bet es cenšos padarīt formatējumu pietiekami jauku, lai tas būtu vairāk lasāms. Es cenšos īstenot toString () metodes, kuru uzturēšana nav pārāk sarežģīta vai dārga, bet kas nodrošina ļoti vienkāršu formatēšanu. Es cenšos izturēties pret nākamajiem sava koda uzturētājiem tā, kā es vēlētos, lai pret mani izturētos izstrādātāji, kuru kodu es kādreiz uzturēšu.

Savā postenī toString () ieviešana, Blohs paziņo, ka izstrādātājam jāizvēlas, vai viņam ir vai nav toString () atgriezt noteiktu formātu. Ja ir paredzēts īpašs formāts, tas ir jādokumentē Javadoc komentāros, un Blohs arī iesaka nodrošināt statisku inicializatoru, kas objektu var atgriezt tā eksemplāra raksturlielumos, pamatojoties uz virkni, ko ģenerējis toString (). Es tam visam piekrītu, bet es uzskatu, ka tas ir vairāk problēmu, nekā lielākā daļa izstrādātāju ir gatavi doties. Blohs arī norāda, ka jebkādas izmaiņas šajā formātā turpmākajos izlaidumos izraisīs sāpes un dusmas cilvēkiem atkarībā no tā (tieši tāpēc es nedomāju, ka ir laba ideja, ja loģika ir atkarīga no toString () izlaide). Ar ievērojamu disciplīnu rakstīt un uzturēt atbilstošu dokumentāciju ar iepriekš noteiktu formātu toString () varētu būt ticams. Tomēr man šķiet nepatikšanas un labāk vienkārši izveidot jaunu un atsevišķu metodi šādiem lietojumiem un atstāt toString () neapgrūtināts.

Nav pieļaujamas blakusparādības

Tikpat svarīga kā toString () ieviešana ir nepieņemama (un noteikti tiek uzskatīta par sliktu formu) tieša vai netieša aicinājuma saņemšana toString () ietekmes loģiku vai novest pie izņēmumiem vai loģiskām problēmām. Autora a toString () metodei jābūt uzmanīgai, lai pirms piekļuves tām pārbaudītu, vai atsauces nav derīgas, lai izvairītos no NullPointerException. Daudzas taktikas, kuras aprakstīju ziņojumā Efektīva Java NullPointerException apstrāde, var izmantot toString () ieviešana. Piemēram, String.valueOf (Object) nodrošina vienkāršu mehānismu nulles drošībai attiecībā uz apšaubāmas izcelsmes atribūtiem.

Tas ir līdzīgi svarīgi arī toString () izstrādātājs pārbauda masīvu izmērus un citus kolekcijas izmērus, pirms mēģina piekļūt elementiem ārpus šīs kolekcijas. Konkrēti, ir pārāk viegli uzskriet StringIndexOutOfBoundsException, mēģinot manipulēt ar String vērtībām ar String.substring.

Jo objekta toString () ieviešanu var viegli izmantot, attīstītājam to apzinīgi neapzinoties, šis padoms, lai pārliecinātos, ka tas neizmet izņēmumus un neveic loģiku (īpaši loģiku, kas maina stāvokli), ir īpaši svarīgs. Pēdējā lieta, ko kāds vēlas, ir tas, ka, reģistrējot instances pašreizējo stāvokli, tiek radīts izņēmums vai izmaiņas stāvoklī un uzvedībā. A toString () ieviešanai faktiski vajadzētu būt tikai lasāmai operācijai, kurā objekta stāvoklis tiek nolasīts, lai ģenerētu virkni atgriešanai. Ja procesā tiek mainīti kādi atribūti, visticamāk, sliktas lietas notiks neparedzamā laikā.

Tā ir mana nostāja, ka a toString () ieviešanai jāietver tikai stāvoklis ģenerētajā virknē, kas ir pieejama tajā pašā procesa telpā tās ģenerēšanas laikā. Man nav attaisnojams, ja ir toString () ieviešana piekļūt attālajiem pakalpojumiem, lai izveidotu instances virkni. Varbūt nedaudz mazāk acīmredzams ir tas, ka gadījumam nevajadzētu aizpildīt datu atribūtus, jo toString () tika izsaukts. The toString () ieviešanā jāziņo tikai par to, kā lietas notiek pašreizējā situācijā, nevis par to, kā tās varētu būt vai būs nākotnē, ja rodas atsevišķi atšķirīgi scenāriji vai ja lietas tiek ielādētas. Lai efektīvi atkļūdotu un diagnosticētu, toString () jāparāda, kādi ir apstākļi, nevis kā tie varētu būt.

Ar cieņu tiek novērtēta vienkārša formatēšana

Kā aprakstīts iepriekš, saprātīga līniju atdalītāju un cilņu izmantošana var būt noderīga, lai garus un sarežģītus gadījumus padarītu patīkamākus, ja tie tiek ģenerēti virknes formātā. Ir arī citi "triki", kas var padarīt lietas jaukākas. Ne tikai to dara String.valueOf (objekts) sniegt dažus nulle aizsardzību, bet tas arī rada nulle kā virkne "null" (kas bieži vien ir vēlamais nulles attēlojums toString () ģenerētajā virknē. Arrays.toString (objekts) ir noderīgs, lai viegli attēlotu masīvus kā virknes (papildu informāciju skatiet manā ierakstā Java masīvu noteikšana).

Iekļaujiet klases nosaukumu toString pārstāvniecībā

Kā aprakstīts iepriekš, noklusējuma toString () nodrošina klases nosaukumu kā daļu no instances attēlojuma. Kad mēs to nepārprotami ignorējam, mēs varam zaudēt šo klases nosaukumu. Parasti tas nav liels darījums, ja reģistrējat instances virkni, jo reģistrēšanas sistēmā tiks iekļauts klases nosaukums. Tomēr es gribētu būt drošā pusē un man vienmēr ir pieejams klases nosaukums. Man vienalga, ja heksadecimālā hash koda attēlojums tiek saglabāts no noklusējuma toString (), bet klases nosaukums var būt noderīgs. Labs piemērs tam ir Throwable.toString (). Es gribētu izmantot šo metodi, nevis getMessage vai getLocalizedMessage, jo pirmais (toString ()) ietver Metamsklases nosaukums, bet pēdējās divas metodes to nedara.

toString () alternatīvas

Mums pašlaik tā nav (vismaz ne standarta pieeja), taču ir runāts par Java objektu klasi, kas ilgi un droši sagatavotu virkni dažādu objektu, datu struktūru un kolekciju attēlojumu. Es neesmu dzirdējis par neseniem panākumiem JDK7 šajā klasē. Standarta klase JDK, kas nodrošināja virkņu objektu attēlojumu pat tad, ja objektu klases definīcijas nesniedza skaidru tekstu toString () būtu noderīgi.

Apache Commons ToStringBuilder var būt vispopulārākais risinājums, lai izveidotu drošas toString () ieviešanas iespējas, izmantojot dažas pamata formatēšanas vadīklas. Esmu iepriekš blogojis vietnē ToStringBuilder, un ir daudz citu tiešsaistes resursu par ToStringBuilder izmantošanu.

Glena Makklūzija Java tehnoloģiju tehniskajā padomā "Writing toString Methods" ir sniegta papildu informācija par toString () metodes rakstīšanu. Vienā no lasītāju komentāriem Džovanni Pelosi paziņo, ka priekšroka deleģēt instances virknes attēlošanu mantojuma hierarhijās no toString () šim nolūkam uzbūvētai delegātu klasei.

Secinājums

Es domāju, ka lielākā daļa Java izstrādātāju atzīst laba vērtību toString () ieviešana. Diemžēl šīs ieviešanas iespējas ne vienmēr ir tik labas vai noderīgas, kā varētu būt. Šajā amatā esmu mēģinājis ieskicēt dažus uzlabošanas apsvērumus toString () ieviešana. Lai gan a toString () metode neietekmēs (vai vismaz nevajadzētu) ietekmēt loģiku kā vienāds (objekts) vai hashCode () metode var uzlabot atkļūdošanu un diagnostikas efektivitāti. Mazāk laika, kas pavadīts, lai noskaidrotu objekta stāvokli, nozīmē vairāk laika problēmas novēršanai, pārvarēšanai interesantākos izaicinājumos un vairāk klientu vajadzību apmierināšanai.

Šo stāstu "Java toString () apsvērumi" sākotnēji publicēja JavaWorld.

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