Ongeldig type in Java

1. Overzicht

Als Java-ontwikkelaars zijn we mogelijk de Ongeldig typ bij een bepaalde gelegenheid en vroeg zich af wat het doel was.

In deze korte tutorial leren we over deze eigenaardige klasse en zien we wanneer en hoe je deze kunt gebruiken en hoe je deze, indien mogelijk, kunt vermijden.

2. Wat is het Ongeldig Type

Sinds JDK 1.1 biedt Java ons de Ongeldig type. Het doel is simpelweg om de leegte retourneer type als een klasse en bevat een Klasse publieke waarde. Het is niet direct instelbaar omdat de enige constructor privé is.

Daarom is de enige waarde die we kunnen toekennen aan een Ongeldig variabele is nul. Het lijkt misschien een beetje nutteloos, maar we zullen nu zien wanneer en hoe dit type te gebruiken.

3. Gebruik

Er zijn enkele situaties wanneer u de Ongeldig type kan interessant zijn.

3.1. Reflectie

Ten eerste kunnen we het gebruiken bij reflectie. Inderdaad, het retourtype van elk leegte methode komt overeen met de Vervalt.TYPE variabele die de Klasse waarde eerder genoemd.

Laten we ons een simpele voorstellen Rekenmachine klasse:

openbare klasse Calculator {privé int resultaat = 0; public int add (int number) {return result + = number; } public int sub (int number) {return result - = number; } public void clear () {resultaat = 0; } public void print () {System.out.println (resultaat); }}

Sommige methoden retourneren een geheel getal, andere geven niets terug. Laten we nu zeggen dat we het moeten doen haal, door reflectie, alle methoden op die geen resultaat opleveren. We zullen dit bereiken door de Vervalt.TYPE variabele:

@Test ongeldig gegevenCalculator_whenGettingVoidMethodsByReflection_thenOnlyClearAndPrint () {Methode [] calculatorMethods = Calculator.class.getDeclaredMethods (); Lijst calculatorVoidMethods = Arrays.stream (calculatorMethods) .filter (methode -> methode.getReturnType (). Is gelijk aan (Void.TYPE)) .collect (Collectors.toList ()); assertThat (calculatorVoidMethods) .allMatch (method -> Arrays.asList ("clear", "print"). bevat (method.getName ())); }

Zoals we kunnen zien, is alleen de Doorzichtig() en afdrukken() methoden zijn opgehaald.

3.2. Merkloos product

Een ander gebruik van de Ongeldig type is met generieke klassen. Stel dat we een methode aanroepen waarvoor een Oproepbaar parameter:

openbare klasse Uitstel {openbare statische V uitstel (opvraagbaar opvraagbaar) gooit Uitzondering {terugkeer opvraagbaar.call (); }}

Maar de Oproepbaar we willen passeren hoeft niets terug te geven. Daarom kunnen we een Oproepbaar:

@Test ongeldig gegevenVoidCallable_whenDiffer_thenReturnNull () gooit uitzondering {Callable callable = nieuwe oproepbare () {@Override openbare ongeldige oproep () {System.out.println ("Hallo!"); null teruggeven; }}; assertThat (Defer.defer (opvraagbaar)). isNull (); }

We zouden een willekeurig type kunnen gebruiken (bijv. Oproepbaar) En terugkomen nul of helemaal geen type (Oproepbaar), maar gebruik makend van Ongeldig stelt duidelijk onze bedoelingen.

We kunnen deze methode ook toepassen op lambda's. In feite is onze Oproepbaar had kunnen worden geschreven als een lambda. Laten we ons een methode voorstellen die een Functie, maar we willen een Functie dat geeft niets terug. Dan moeten we het gewoon terug laten komen Ongeldig:

openbare statische R defer (Functie, functie, T arg) {retourfunctie. toepassen (arg); }
@Test ongeldig gegevenVoidFunction_whenDiffer_thenReturnNull () {Functie functie = s -> {System.out.println ("Hallo" + s + "!"); null teruggeven; }; assertThat (Defer.defer (functie, "Wereld")). isNull (); }

4. Hoe gebruik je het niet?

Nu hebben we enkele toepassingen van de Ongeldig type. Maar zelfs als het eerste gebruik helemaal in orde is, we zouden het gebruik van Ongeldig in generieke geneesmiddelen indien mogelijk. Inderdaad, een retourtype tegenkomen dat de afwezigheid van een resultaat vertegenwoordigt en alleen nul kan omslachtig zijn.

We zullen nu zien hoe we deze situaties kunnen vermijden. Laten we eerst eens kijken naar onze methode met de Oproepbaar parameter. Om te voorkomen dat u een Oproepbaar, kunnen we een andere methode aanbieden met een Runnable parameter in plaats daarvan:

openbare statische leegte uitstellen (Runnable uitvoerbaar) {runnable.run (); }

Dus we kunnen het een Runnable die geen enkele waarde teruggeeft en zo het nutteloze wegdoet retourneer null:

Runnable runnable = nieuw Runnable () {@Override public void run () {System.out.println ("Hallo!"); }}; Defer.defer (uitvoerbaar);

Maar wat als het Uitstellen klasse is niet van ons om te wijzigen? Dan kunnen we ons houden aan de Oproepbaar optie of maak een andere klas aan met een Runnable en het uitstellen van de oproep naar de Uitstellen klasse:

openbare klasse MyOwnDefer {openbare statische leegte uitstel (Runnable uitvoerbaar) gooit uitzondering {Defer.defer (nieuwe oproep () {@Override openbare leegte oproep () {runnable.run (); retourneer null;}}); }}

Door dat te doen, kapselen we het omslachtige deel voor eens en voor altijd in onze eigen methode, waardoor toekomstige ontwikkelaars een eenvoudigere API kunnen gebruiken.

Hetzelfde kan natuurlijk worden bereikt voor Functie. In ons voorbeeld is de Functie retourneert niets, dus we kunnen een andere methode bieden met een Klant in plaats daarvan:

openbare statische leegte uitstellen (Consumer consumer, T arg) {consumer.accept (arg); }

Wat als onze functie geen enkele parameter accepteert? We kunnen een Runnable of maak onze eigen functionele interface (als dat duidelijker lijkt):

openbare interface Actie {void execute (); }

Vervolgens overbelasten we de uitstellen() methode opnieuw:

openbare statische leegte uitstellen (actie actie) {action.execute (); }
Actie action = () -> System.out.println ("Hallo!"); Defer.defer (actie);

5. Conclusie

In dit korte artikel hebben we de Java behandeld Ongeldig klasse. We hebben gezien wat het doel was en hoe we het moesten gebruiken. We hebben ook enkele alternatieven voor het gebruik ervan geleerd.

Zoals gewoonlijk is de volledige code van dit artikel te vinden op onze GitHub.