Java voliteľná ako návratový typ

1. Úvod

The Voliteľné typ bol zavedený v prostredí Java 8. Poskytuje jasný a explicitný spôsob sprostredkovania správy, že nemusí existovať hodnota, bez použitia nulový.

Pri získavaní Voliteľné návratový typ, pravdepodobne skontrolujeme, či hodnota chýba, čo povedie k menšiemu počtu NullPointerExceptions v aplikáciách. Avšak Voliteľné typ nie je vhodný na všetkých miestach.

Aj keď ho môžeme použiť všade, kde to považujeme za vhodné, v tomto tutoriáli sa zameriame na niektoré osvedčené postupy používania Voliteľné ako návratový typ.

2. Voliteľné ako návratový typ

An Voliteľné type môže byť návratovým typom pre väčšinu metód, okrem niektorých scenárov, o ktorých sa ďalej hovorí v tomto výučbe.

Väčšinou sa vracia Voliteľné je v pohode:

public static Voliteľné findUserByName (názov reťazca) {User user = usersByName.get (name); Voliteľné opt = Optional.ofNullable (užívateľ); návrat opt; }

Je to užitočné, pretože môžeme použiť Voliteľné API vo volacej metóde:

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

Je tiež vhodné, aby statická alebo úžitková metóda vrátila Voliteľné hodnotu. Existuje však veľa situácií, kedy by sme sa nemali vrátiť voliteľné typu.

3. Kedy sa nevrátiť Voliteľné

Pretože Voliteľné je obálka a trieda založená na hodnotách, existujú niektoré operácie, proti ktorým sa nedá urobiť Voliteľné objekt. Mnohokrát je jednoducho lepšie vrátiť skutočný typ ako an Voliteľné typu.

Všeobecne možno povedať, že pre hľadačov v POJO je vhodnejšie vrátiť skutočný typ, nie znak Voliteľné typu. Pre Entity Beans, dátové modely a DTO je obzvlášť dôležité mať tradičné getre.

Ďalej preskúmame niektoré dôležité prípady použitia.

3.1. Serializácia

Poďme si predstaviť, že máme jednoduchú entitu:

verejná trieda Sock implementuje Serializable {Integer size; Voliteľný pár; // ... zakladatelia a zakladatelia}

Toto vlastne nebude fungovať vôbec. Keby sme sa to pokúsili serializovať, dostali by sme NotSerializableException:

nový ObjectOutputStream (nový ByteArrayOutputStream ()). writeObject (nový Sock ()); 

A naozaj, počas serializácie Voliteľné môže pracovať s inými knižnicami, určite to pridáva zbytočnú zložitosť.

Poďme sa pozrieť na inú aplikáciu s rovnakým nesúladom serializácie, tentokrát s JSON.

3.2. JSON

Moderné aplikácie neustále prevádzajú objekty Java na JSON. Ak getter vráti an Voliteľné typu, s najväčšou pravdepodobnosťou uvidíme vo finálnom JSONe nejakú neočakávanú dátovú štruktúru.

Povedzme, že máme fazuľu s voliteľnou vlastnosťou:

private String meno; public Optional getFirstName () {return Optional.ofNullable (firstName); } public void setFirstName (reťazec firstName) {this.firstName = firstName; }

Takže ak použijeme Jackson na serializáciu inštancie Voliteľné, dostaneme:

{"firstName": {"present": true}} 

Ale to, čo by sme skutočne chceli, je:

{"firstName": "Baeldung"}

Takže Voliteľné je bolesť pre prípady použitia serializácie. Ďalej sa pozrime na bratranca k serializácii: zápis údajov do databázy.

3.3. JPA

V JPA by getter, setter a pole mali mať meno a typovú dohodu. Napríklad a krstné meno pole typu String by mal byť spárovaný s getrom s názvom getFirstName ktorá tiež vráti a String.

Dodržiavanie tejto konvencie uľahčuje niekoľko vecí, vrátane použitia reflexie v knižniciach ako Hibernate, a poskytuje nám tak veľkú podporu mapovania objektov a vzťahov.

Pozrime sa na náš prípad rovnakého použitia voliteľné krstné meno v POJO.

Tentokrát to však bude subjekt JPA:

@Entity verejná trieda UserOptionalField implementuje Serializable {@Id private long userId; súkromné ​​Voliteľné meno; // ... zakladatelia a zakladatelia}

A poďme ďalej a skúsme to vydržať:

UserOptionalField user = nový UserOptionalField (); user.setUserId (1l); user.setFirstName (Optional.of ("Baeldung")); entityManager.persist (užívateľ);

Je nám smutné, že narazíme na chybu:

Spôsobené: javax.persistence.PersistenceException: [PersistenceUnit: com.baeldung.optionalReturnType] Nie je možné vytvoriť Hibernate SessionFactory na org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException (EntityManagerImoteBuildEduTeBeReTeBeReBeReBeReBeReBeReBeReBeBeReBeReBeReBeReBeReBeReBeReBeReBeBlReBeBeJUJA5E5e5E5E4 .boot.internal.EntityManagerFactoryBuilderImpl.build (EntityManagerFactoryBuilderImpl.java:941) na adrese org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory (HibernatePersistenceProvider.java:56) at javax.persist.seist.ersist persistence.Persistence.createEntityManagerFactory (Persistence.java:54) na adrese com.baeldung.optionalReturnType.PersistOptionalTypeExample. (PersistOptionalTypeExample.java:11) Spôsobené: org.hibernate.MappingException: nie je možné určiť typ: tabuľka: UserOptionalField, pre stĺpce: [org.hibernate.mapping.Column (firstName)]

Mohli by sme to vyskúšať odchylne od tejto normy. Napríklad by sme si mohli nehnuteľnosť ponechať ako a String, ale zmeňte getter:

@Column (nullable = true) private String firstName; public Optional getFirstName () {return Optional.ofNullable (firstName); }

Zdá sa, že by sme mohli mať obe možnosti: mať Voliteľné návratový typ pre geter a perzistentné pole krstné meno.

Avšak teraz, keď nie sme v súlade s naším getrom, setterom a poľom, bude ťažšie využívať predvolené hodnoty JPA a nástroje zdrojového kódu IDE.

Kým nebude mať JPA elegantnú podporu Voliteľné typu, mali by sme sa držať tradičného kódu. Je to jednoduchšie a lepšie:

private String meno; // ... tradičný getter a setter

Poďme sa konečne pozrieť na to, ako to ovplyvňuje frontend - skontrolujte, či problém, s ktorým sa stretneme, znie povedome.

3.4. Expresné jazyky

Príprava DTO pre front-end predstavuje podobné ťažkosti.

Predstavme si napríklad, že na čítanie našich používame šablóny JSP UserOptional DTO krstné meno z požiadavky:

Pretože je to Voliteľné, neuvidíme „Baeldung„. Namiesto toho uvidíme String zastúpenie Voliteľné typ:

Voliteľné [Baeldung] 

A to nie je problém iba s JSP. Akýkoľvek šablónovaný jazyk, či už je to Velocity, Freemarker alebo niečo iné, bude musieť k tomu pridať podporu. Do tej doby pokračujme v zjednodušovaní našich DTO.

4. Záver

V tomto tutoriáli sme sa naučili, ako môžeme vrátiť Voliteľné objekt a ako naložiť s týmto druhom návratovej hodnoty.

Na druhej strane sme sa tiež dozvedeli, že existuje veľa scenárov, ktoré by sme radšej nepoužili Voliteľné návratový typ pre getter. Zatiaľ čo môžeme použiť Voliteľné napíšte ako náznak, že nemusí existovať nenulová hodnota, mali by sme byť opatrní, aby sme nadmerne nepoužívali Voliteľné návratový typ, najmä v getri typu bean entity alebo DTO.

Zdrojový kód príkladov v tomto tutoriále nájdete na GitHub.


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