Java választható visszatérési típusként

1. Bemutatkozás

A Választható A tipust a Java 8-ban vezették be. Világos és egyértelmű módot kínál arra, hogy használat nélkül továbbítsuk azt az üzenetet, hogy nem lehet érték nulla.

Amikor egy Választható visszatérési típus, valószínűleg ellenőrizzük, hogy hiányzik-e az érték, ami kevesebbet eredményez NullPointerExceptions az alkalmazásokban. Azonban a Választható típus nem mindenhol alkalmas.

Bár felhasználhatjuk bárhol, ahol jónak látjuk, ebben az oktatóanyagban a használat néhány bevált gyakorlatára összpontosítunk Választható mint visszatérési típus.

2. Választható mint Return Type

An Választható A type lehet a legtöbb módszer visszatérési típusa, kivéve néhány, az oktatóanyagban később tárgyalt forgatókönyvet.

Legtöbbször egy Választható nagyon jó:

public static Opcionális findUserByName (karakterlánc neve) {User user = usersByName.get (név); Opcionális opció = Opcionális.Nullable (felhasználó); return opt; }

Ez hasznos, mivel használhatjuk a Választható API a hívási módszerben:

public static void changeUserName (String oldFirstName, String newFirstName) {findUserByFirstName (oldFirstName) .ifPresent (user -> user.setFirstName (newFirstName)); }

Statikus vagy segédprogram esetén is helyénvaló az Választható érték. Sok helyzet azonban nem térhet vissza egy Opcionális típus.

3. Mikor nem tér vissza Választható

Mivel Választható egy burkoló és értékalapú osztály, vannak olyan műveletek, amelyek ellen nem lehet végrehajtani Választható tárgy. Sokszor egyszerűen jobb, ha a tényleges típust adjuk vissza an helyett Választható típus.

Általánosságban elmondható, hogy a POJO-ban szerzett személyek számára inkább a tényleges típust adja vissza, nem pedig egy Választható típus. Különösen fontos, hogy az entitásbaboknak, az adatmodelleknek és a DTO-knak hagyományos getterek legyenek.

Az alábbiakban megvizsgálunk néhány fontos felhasználási esetet.

3.1. Serializálás

Képzeljük el, hogy van egy egyszerű entitásunk:

nyilvános osztályú Zoknieszközök Serializálható {Egész szám; Opcionális pár; // ... getterek és beállítók}

Ez valójában egyáltalán nem fog működni. Ha megpróbálnánk ezt sorosítani, akkor kapnánk egy NotSerializableException:

új ObjectOutputStream (új ByteArrayOutputStream ()). writeObject (új Sock ()); 

És valóban, miközben sorosít Választható együttműködhet más könyvtárakkal, minden bizonnyal hozzáteszi azt, ami felesleges lehet.

Vizsgáljuk meg ugyanezen szerializálási eltérés egy másik alkalmazását, ezúttal a JSON-nal.

3.2. JSON

A modern alkalmazások a Java objektumokat állandóan JSON-vá konvertálják. Ha egy getter egy Választható típusú, valószínűleg váratlan adatstruktúrát fogunk látni a végső JSON-ban.

Tegyük fel, hogy van egy babunk opcionális tulajdonsággal:

privát karakterlánc keresztnév; public Opcionális getFirstName () {return Optional.ofNullable (keresztnév); } public void setFirstName (String keresztnév) {this.firstName = keresztnév; }

Tehát, ha Jacksont használunk egy példány sorosítására Választható, megkapjuk:

{"keresztnév": {"jelen": igaz}} 

De amire igazán vágyunk:

{"keresztnév": "Baeldung"}

Így, Választható fájdalom a szerializációs használat eseteiben. Ezután nézzük meg a szerializálás unokatestvérét: adatok írása egy adatbázisba.

3.3. JPA

A JPA-ban a getternek, a setternek és a mezőnek meg kell adnia a nevet és a típusmegállapodást. Például a keresztnév típusú mező Húr nevű getterrel kell párosítani getFirstName hogy vissza is ad egy Húr.

Ennek a konvenciónak a követése számos dolgot egyszerűbbé tesz, beleértve a reflexió használatát olyan könyvtárakban, mint a Hibernate, hogy nagyszerű támogatást nyújtsunk az objektum-reláció leképezéshez.

Vessünk egy pillantást ugyanarra a felhasználási esetre opcionális keresztnév a POJO-ban.

Ezúttal azonban egy JPA-entitás lesz:

A @Entity public class UserOptionalField megvalósítja a Serializable {@Id private long userId; privát Opcionális keresztnév; // ... getterek és beállítók}

És menjünk előre, és próbáljuk meg kitartani:

UserOptionalField user = new UserOptionalField (); user.setUserId (1l); user.setFirstName (Opcionális.of ("Baeldung")); entitásManager.persist (felhasználó);

Sajnos hibába ütközünk:

Okozta: javax.persistence.PersistenceException: [PersistenceUnit: com.baeldung.optionalReturnType] Nem lehet Hibernate SessionFactoryot felépíteni az org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.plactoryExanExtranExanExanExanExanExanExanExanExanExanExanEdealityExanExanElectEnternet .boot.internal.EntityManagerFactoryBuilderImpl.build (EntityManagerFactoryBuilderImpl.java:941) at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory (HibernatePersistenceProvider.java:56) at javax.persistence.Persistence.createEntityManagerFactory (Persistence.java:79) at javax. persistence.Persistence.createEntityManagerFactory (Persistence.java:54) at com.baeldung.optionalReturnType.PersistOptionalTypeExample. (PersistOptionalTypeExample.java:11) Okozta: org.hibernate.MappingExutcity for: Could táblázat: UserOptionalField, oszlopokhoz: [org.hibernate.mapping.Column (keresztnév)]

Megpróbálhatnánk ettől a mércétől eltérve. Például megtarthatnánk az ingatlant a Húr, de változtassa meg a kaput:

@ Oszlop (nullable = true) privát karakterlánc keresztnév; public Opcionális getFirstName () {return Optional.ofNullable (keresztnév); }

Úgy tűnik, hogy mindkettőnk lehet: van egy Választható a getter visszatérési típusa és egy tartós mező keresztnév.

Most azonban, amikor nem vagyunk összhangban a getterrel, a setterrel és a mezővel, nehezebb lesz kihasználni a JPA alapértelmezett értékeit és az IDE forráskód eszközeit.

Amíg a JPA elegáns támogatással nem rendelkezik Választható típusú, ragaszkodnunk kell a hagyományos kódhoz. Ez egyszerűbb és jobb:

privát karakterlánc keresztnév; // ... hagyományos getter és szetter

Végül vessünk egy pillantást arra, hogy ez milyen hatással van a kezelőfelületre - ellenőrizzük, hogy a probléma, amellyel összefutunk, ismerősen hangzik-e.

3.4. Kifejezési nyelvek

A DTO előkészítése a kezelőfelülethez hasonló nehézségekkel jár.

Képzeljük el például, hogy JSP sablonokat használunk az olvasáshoz UserOptional DTO-k keresztnév a kérésből:

Mivel ez egy Választható, nem fogjuk látniBaeldung“. Ehelyett meglátjuk a Húr a Választható típus:

Opcionális [Baeldung] 

És ez nem csak a JSP-vel van probléma. Bármely sablonnyelvnek, legyen az Velocity, Freemarker vagy valami más, ehhez hozzá kell adnia a támogatást. Addig folytassuk a DTO-k egyszerűségét.

4. Következtetés

Ebben az oktatóanyagban megtanultuk, hogyan adhatunk vissza egy Választható objektum, és hogyan kell kezelni ezt a fajta visszatérési értéket.

Másrészt azt is megtanultuk, hogy sok olyan forgatókönyv létezik, amelyet jobb lenne, ha nem használnánk Választható return típus egy getterhez. Míg használhatjuk Választható írja be arra utalásként, hogy nem lehet nem null érték, vigyáznunk kell, hogy ne használjuk túl a Választható return típus, különösen egy entitás bab vagy DTO getterében.

Az oktatóanyag példáinak forráskódja a GitHubon található.