Programiranje

Začnite s sklici na metode v Javi

Skupaj z lambdami je Java SE 8 prinesel sklicevanja na jezik Java. Ta vadnica ponuja kratek pregled referenc na metode v Javi, nato pa jih začnete uporabljati s primeri Java kode. Na koncu vadnice boste vedeli, kako se s sklici na metode sklicujete na statične metode razreda, vezane in nevezane ne-statične metode in konstruktorje ter kako jih uporabljate za sklicevanje na metode primerkov v superklasi in trenutnem razredu vrste. Razumeli boste tudi, zakaj so mnogi razvijalci Java lambda izraze in sklice na metode sprejeli kot čistejšo in preprostejšo alternativo anonimnim razredom.

Upoštevajte, da so primeri kode v tej vadnici združljivi z JDK 12.

prenos Prenesite kodo Prenesite izvorno kodo, na primer programe v tej vadnici. Ustvaril Jeff Friesen za JavaWorld.

Referenca metode: Primer

Moja prejšnja vadnica Java 101 je uvedla lambda izraze, ki se uporabljajo za definiranje anonimnih metod, ki jih je nato mogoče obravnavati kot primerke funkcionalnega vmesnika. Včasih lambda izraz ne naredi nič drugega kot poklic obstoječe metode. Na primer, naslednji fragment kode uporablja lambda za priklic System.outje nične natisnjene številke metoda na samem argumenta lambda--svrsta osebe še ni znana:

(s) -> System.out.println (s)

Lambda predstavlja (s) kot njegov formalni seznam parametrov in telo kode, katere System.out.println (s) izrazi svrednost v standardni izhodni tok. Nima eksplicitne vrste vmesnika. Namesto tega prevajalnik iz okoliškega konteksta sklepa, kateri funkcionalni vmesnik naj ustvari. Na primer, upoštevajte naslednji fragment kode:

Potrošniški potrošnik = (s) -> System.out.println (s);

Prevajalnik analizira prejšnjo izjavo in ugotovi, da java.util.function.Consumer vnaprej določeni funkcionalni vmesniki neveljavno sprejme (T t) metoda se ujema s formalnim seznamom parametrov lambda ((s)). To tudi določa sprejme ()je praznino vrnitev vrste ujema println ()je praznino vrsta vrnitve. Lambda je tako vezan do Potrošnik.

Natančneje, lambda je dolžna Potrošnik. Prevajalnik generira kodo tako, da se prikliče Potrošnikje void accept (String s) rezultira z argumentom niza, ki mu je bil poslan s se prenaša na System.outje void println (nizi) metoda. Ta klic je prikazan spodaj:

consumer.accept ("Pozdravljeni"); // Prenesite "Hello" v lambda telo. Natisnite Hello na standardni izhod.

Če želite shraniti pritiske tipk, lahko lambdo zamenjate z sklic na metodo, kar je kompaktno sklicevanje na obstoječo metodo. Na primer, naslednji fragment kode nadomesti (String s) -> System.out.println (s) s System.out :: println, kje :: pomeni, da System.outje void println (nizi) metoda se sklicuje:

Potrošnik consumer2 = System.out :: println; // Referenca metode je krajša. consumer2.accept ("Pozdravljeni"); // Prenesite "Hello" v lambda telo. Natisnite Hello na standardni izhod.

Za prejšnjo referenco metode ni treba navajati formalnega seznama parametrov, ker lahko prevajalnik sklepa na ta seznam Potrošnik Ta parametrizirana vrsta java.lang.String argument dejanskega tipa nadomesti T v neveljavno sprejme (T t)in je tudi vrsta posameznega parametra v lambda telesu System.out.println () klic metode.

Poglobljena sklicevanja na metode

A sklic na metodo je skladenjska bližnjica za ustvarjanje lambde iz obstoječe metode. Namesto zagotavljanja izvedbenega telesa se sklic na metodo nanaša na metodo obstoječega razreda ali predmeta. Tako kot pri lambdi tudi referenca metode zahteva ciljni tip.

Sklice na metode lahko uporabite za sklicevanje na statične metode razreda, vezane in nevezane ne-statične metode in konstruktorje. Sklice na metode lahko uporabite tudi za sklicevanje na metode primerka v superklasi in trenutnih tipih razredov. Predstavil vam bom vsako od teh referenčnih kategorij metod in pokazal, kako se uporabljajo v majhni predstavitvi.

Preberite več o referencah metod

Po branju tega oddelka si oglejte reference metode v Javi 8 (Toby Weston, februar 2014) za večji vpogled v sklice na metode v vezanih in nevezanih ne-statičnih kontekstih metode.

Sklicevanja na statične metode

A sklic na statično metodo se nanaša na statično metodo v določenem razredu. Njegova skladnja je className::staticMethodName, kje className identificira razred in staticMethodName identificira statično metodo. Primer je Celo število :: bitCount. Seznam 1 prikazuje sklic na statično metodo.

Seznam 1. MRDemo.java (različica 1)

uvoz java.util.Arrays; uvoz java.util.function.Consumer; javni razred MRDemo {javna statična void main (String [] args) {int [] array = {10, 2, 19, 5, 17}; Potrošniški potrošnik = Polja :: sort; consumer.accept (matrika); for (int i = 0; i <array.length; i ++) System.out.println (matrika [i]); System.out.println (); int [] array2 = {19, 5, 14, 3, 21, 4}; Potrošniški potrošnik2 = (a) -> Arrays.sort (a); consumer2.accept (array2); for (int i = 0; i <array2.length; i ++) System.out.println (array2 [i]); }}

Seznam 1 glavni () metoda razvrsti par celoštevilskih nizov prek java.util.Arrays razredov statično razvrščanje praznin (int [] a) metoda, ki se prikaže v referenčni referenci statične metode in enakovrednih kontekstih lambda izraza. Po razvrščanju matrike a za zanka natisne vsebino razvrščenega polja v standardni izhodni tok.

Preden lahko uporabimo referenco metode ali lambdo, mora biti ta vezana na funkcijski vmesnik. Uporabljam vnaprej določeno Potrošnik funkcijski vmesnik, ki ustreza referenčnim / lambda zahtevam metode. Operacija razvrščanja se začne s predajo matrike, ki naj bo razvrščena Potrošnikje sprejme () metoda.

Sestavi seznam 1 (javac MRDemo.java) in zaženite aplikacijo (java MRDemo). Opazili boste naslednji izhod:

2 5 10 17 19 3 4 5 14 19 21

Sklicevanja na vezane nestatične metode

A vezana nestetična referenca metode se nanaša na nestatično metodo, ki je vezana na sprejemnik predmet. Njegova skladnja je objectName::instanceMethodName, kje objectName identificira sprejemnik in instanceMethodName identificira metodo primerka. Primer je s :: trim. Seznam 2 prikazuje vezano nestetično referenco metode.

Seznam 2. MRDemo.java (različica 2)

uvoz java.util.function.Supplier; javni razred MRDemo {public static void main (String [] args) {String s = "Hitra rjava lisica je preskočila lenega psa"; tisk (s :: dolžina); print (() -> s.length ()); print (nov dobavitelj () {@Override public Integer get () {return s.length (); // zapre nad s}}); } javni statični void tisk (dobavitelj dobavitelj) {System.out.println (dobavitelj.get ()); }}

Seznam 2 glavni () metoda dodeli niz Vrvica spremenljivka s in nato prikliče natisni () class s funkcijo za pridobitev dolžine tega niza kot argumenta te metode. natisni () se sklicuje na referenco metode (s :: dolžina -- dolžina () je vezan na s), enakovreden lambda in enakovredni anonimni kontekst razreda.

Določil sem natisni () za uporabo java.util.function.Supplier vnaprej določen funkcionalni vmesnik, katerega dobili () vrne dobavitelja rezultatov. V tem primeru je Dobavitelj primerek posredovano natisni () izvaja svoje dobili () metoda za vrnitev s.length (); natisni () izpiše to dolžino.

s :: dolžina uvaja zaporo, ki se zapre s. To lahko jasneje vidite v primeru lambda. Ker lambda nima argumentov, je vrednost s je na voljo samo v priloženem obsegu. Zato je lambda telo zapiralo, ki se zapre s. Primer anonimnega razreda to naredi še bolj jasno.

Sestavite seznam 2 in zaženite aplikacijo. Opazili boste naslednji izhod:

44 44 44

Sklicevanja na nevezane nestatične metode

An nevezane sklicevanje na statično metodo se nanaša na nestatično metodo, ki ni vezana na objekt sprejemnika. Njegova skladnja je className::instanceMethodName, kje className identificira razred, ki razglasi metodo primerka in instanceMethodName identificira metodo primerka. Primer je String :: toLowerCase.

String :: toLowerCase je nevezana nestetična referenca metode, ki identificira nestatično String toLowerCase () metoda Vrvica razred. Ker pa nestatična metoda še vedno zahteva sprejemni objekt (v tem primeru a Vrvica objekt, ki se uporablja za priklic toLowerCase () prek reference reference) navidezni stroj ustvari objekt sprejemnika. toLowerCase () bo pri tem predmetu poklican. String :: toLowerCase določa metodo, ki traja en sam Vrvica argument, ki je predmet prejemnika, in vrne a Vrvica rezultat. String :: toLowerCase () je enakovredno lambdi (String s) -> {return s.toLowerCase (); }.

Navedba 3 prikazuje to nevezano nestetično referenco metode.

Seznam 3. MRDemo.java (različica 3)

uvoz java.util.function.Function; javni razred MRDemo {public static void main (String [] args) {print (String :: toLowerCase, "STRING TO LOWERCASE"); print (s -> s.toLowerCase (), "STRING TO LOWERCASE"); print (nova funkcija () {@Override public String apply (String s) // prejme argument v parametru s; {// ni treba zapreti nad s return s.toLowerCase ();}}, "STRING TO LOWERCASE" ); } javni statični void izpis (funkcija funkcije, nizi s) {System.out.println (function.apply (s)); }}

Seznam 3 glavni () metoda prikliče natisni () class class s funkcionalnostjo za pretvorbo niza v male črke in niz, ki ga je treba pretvoriti kot argumente metode. natisni () se sklicuje na referenco metode (String :: toLowerCase, kje toLowerCase () ni vezan na uporabniško določen objekt) in enakovreden lambda in anonimni kontekst razreda.

Določil sem natisni () za uporabo java.util.function.Function vnaprej določen funkcionalni vmesnik, ki predstavlja funkcijo, ki sprejme en argument in ustvari rezultat. V tem primeru je Funkcija primerek posredovano natisni () izvaja svoje R velja (T t) metoda za vrnitev s.toLowerCase (); natisni () izpiše ta niz.

Čeprav je Vrvica del String :: toLowerCase izgleda, da je referenca na razred, sklican je le na primerek tega razreda. Primer anonimnega razreda to naredi bolj očiten. Upoštevajte, da v primeru anonimnega razreda lambda prejme argument; ne zapre nad parametrom s (tj. ne gre za zaprtje).

Sestavite seznam 3 in zaženite aplikacijo. Opazili boste naslednji izhod:

niz v male črke niz v male črke v male črke

Sklicevanja na konstruktorje

Sklic na metodo lahko uporabite za sklicevanje na konstruktor, ne da bi ustvarili imenovani razred. Ta vrsta reference metode je znana kot referenca konstruktorja. Njegova skladnja je className:: novo. className mora podpirati ustvarjanje predmetov; ne more imenovati abstraktnega razreda ali vmesnika. Ključna beseda novo imenuje referenčni konstruktor. Tu je nekaj primerov:

  • Znak :: novo: enakovredno lambdi (Znak ch) -> nov znak (ch)
  • Dolgo :: novo: enakovredno lambdi (dolga vrednost) -> nova dolga (vrednost) ali (String s) -> new Long (s)
  • ArrayList :: novo: enakovredno lambdi () -> nov ArrayList ()
  • float [] :: novo: enakovredno lambdi (int velikost) -> nov plovec [velikost]

Zadnji referenčni primer konstruktorja namesto vrste razreda določa vrsto matrike, vendar je načelo enako. Primer prikazuje sklic na konstruktor matrike do "konstruktorja" vrste matrike.

Če želite ustvariti referenco konstruktorja, podajte novo brez konstruktorja. Ko razred, kot je java.lang.Long razglasi več konstruktorjev, prevajalnik primerja vrsto funkcionalnega vmesnika z vsemi konstruktorji in izbere najboljše ujemanje. Seznam 4 prikazuje sklic na konstruktor.

Seznam 4. MRDemo.java (različica 4)

uvoz java.util.function.Supplier; javni razred MRDemo {public static void main (String [] args) {Dobavitelj dobavitelja = MRDemo :: new; System.out.println (dobavitelj.get ()); }}

Seznam 4 MRDemo :: novo sklic na konstruktor je enakovreden lambda () -> nov MRDemo (). Izraz dobavitelj.get () izvrši to lambdo, ki prikliče MRDemoprivzeti konstruktor brez argumentov in vrne MRDemo predmet, ki se posreduje System.out.println (). Ta metoda pretvori objekt v niz, ki ga natisne.

Zdaj predpostavimo, da imate razred s konstruktorjem brez argumenta in konstruktorjem, ki sprejme argument, in želite poklicati konstruktor, ki sprejme argument. To nalogo lahko dosežete z izbiro drugega funkcionalnega vmesnika, na primer vnaprej določenega Funkcija vmesnik, prikazan v seznamu 5.

Seznam 5. MRDemo.java (različica 5)

uvoz java.util.function.Function; javni razred MRDemo {ime zasebnega niza; MRDemo () {name = ""; } MRDemo (ime niza) {this.name = ime; System.out.printf ("MRDemo (ime niza), poklicano z% s% n", ime); } public static void main (String [] args) {Function function = MRDemo :: new; System.out.println (function.apply ("neko ime")); }}

Funkcija funkcija = MRDemo :: novo; povzroči, da prevajalnik poišče konstruktor, ki zajema Vrvica argument, ker Funkcijaje uporabi () metoda zahteva en sam (v tem kontekstu) Vrvica prepir. Izvršitev function.apply ("neko ime") Rezultati v "neko ime" se prenaša na MRDemo (ime niza).

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