КампутарыПраграмаванне

Java Generics: апісанне і метады

Пачынаючы з самага з'яўлення мова Java зведаў масу змяненняў, якія, несумненна, прыўнеслі станоўчыя моманты ў яго функцыянальнасць. Адным з такіх значных змяненняў з'яўляецца ўвядзенне Java Generic або абагульнення. Дадзеная функцыянальнасць зрабіла мова не толькі больш гнутка і універсальнейшы, але і нашмат бяспечней ў плане прывядзення тыпаў дадзеных.

Справа ў тым, што да ўвядзення дженеріков абагульнены код у Java можна было ствараць, толькі аперуючы спасылкамі тыпу Object. Такія спасылкі можна прысвойваць любому аб'екта. Бо ўсе класы ў Java з'яўляюцца няяўныя спадкаемцамі класа Object. Аднак такі падыход з'яўляецца патэнцыйным крыніцай шматлікіх памылак, звязаных з бяспекай тыпаў пры відавочным пераўтварэнні аб'екта з Object да мэтавага тыпу. Пры выкарыстанні абагульненняў ўсё прывядзення выконваюцца няяўна і аўтаматычна, што выключае нават патэнцыйную магчымасць ўзнікнення памылак.

Java Generics: апісанне і прыклад

Разбяром просты прыклад прымянення абагульнення да звычайнага класу на малюнку ніжэй. І ўжо затым прыступім да дэталёвага разгляду ўсіх тонкасцяў і нюансаў Java Generic.

Звярніце ўвагу на тое, якім чынам адбываецца аб'яву класа Pair. Адразу пасля імя класа адкрываюцца вуглавыя дужкі, у якіх паказваецца літара T. Яна ўяўляе сабой своеасаблівы запаўняльнік, які ў працэсе стварэння асобніка дадзенага класа будзе заменены пэўным тыпам. Выглядае гэта наступным чынам: Pair obj = new Pair (). Варта адзначыць, што замест T можна паказваць любую літару, але, як правіла, выкарыстоўваюць T, V або E.

Заўвага: пачынаючы з восьмай версіі Java, паказаўшы мэтавай тып пры аб'яўленні спасылкі, вуглавыя дужкі ў канструктару можна пакінуць пустымі. Так прыведзены вышэй прыклад можна перапісаць наступным чынам: Pair obj = new Pair <> ().

Калі клас абвешчаны такім чынам, далей у яго целе замест канкрэтных тыпаў палёў, спасылак і што вяртаюцца метадамі аб'ектаў можна выкарыстоўваць гэтую літару. Паколькі T пры стварэнні аб'екта класа замяняецца пэўным тыпам, поля first і second ў дадзеным выпадку будуць мець тып Integer.

Вынікаючы логіцы, аргументы firstItem і secondItem, якія перадаюцца адпавядае канструктару, таксама павінны мець тып Integer або яго падкласа. Калі вы паспрабуеце перадаць тып дадзеных, які адрозніваецца ад таго, што быў пазначаны пры стварэнні аб'екта, кампілятар не прапусціць гэтую памылку. Так, канструктар з аргументамі пры стварэнні аб'екта будзе мець наступны выгляд: Pair obj = new Pair <> (new Integer (1), new Integer (2)). Тое ж самае ставіцца да аргументаў метадаў setFirst і setSecond. І як вы ўжо, напэўна, здагадаліся, метады getFirst і getSecond будуць вяртаць значэння тыпу Integer.

Абагульнены клас з некалькімі параметрамі тыпаў

У абагульненых класах таксама можна аб'яўляць некалькі параметраў тыпу, якія задаюцца ў кутніх дужках праз коску. Перапрацаваны пад такі выпадак клас Pair прадстаўлены на малюнку ніжэй.

Як бачым, пры стварэнні асобніка такога класа ў кутніх дужках варта паказваць тое ж колькасць тыпаў, што і параметраў. Калі вы знаёмыя з такім выглядам структуры дадзеных, як Map, то вы маглі заўважыць, што там выкарыстоўваецца сапраўды такі ж прынцып. Там першы аргумент вызначае тып ключа, а другі - тып значэння. Варта адзначыць, што тыпы перадаюцца пры стварэнні аб'екта аргументаў могуць супадаць. Так, наступнае аб'явы асобніка класа Pair з'яўляецца абсалютна карэктным: Pair obj.

Некаторыя асаблівасці абагульненняў

Перад тым як ісці далей, варта адзначыць, што кампілятар Java не стварае ніякіх розных версій класа Pair. На самай справе ў працэсе кампіляцыі ўся інфармацыя аб абагульненай тыпе выдаляецца. Замест гэтага выконваецца прывядзенне адпаведных тыпаў, ствараючы адмысловую версію класа Pair. Аднак у самой праграме па-ранейшаму існуе адзіная абагульненая версія дадзенага класа. Гэты працэс называецца ў Java Generic ачыстка тыпу.

Адзначым важны момант. Спасылкі на розныя версіі аднаго і таго ж java generic класа не могуць паказваць на адзін і той жа аб'ект. Гэта значыць, дапусцім, у нас ёсць дзве спасылкі: Pair obj1 і Pair obj2. Такім чынам, у радку obj1 = obj2 паўстане памылка. Хоць абедзве зменныя ставяцца да тыпу Pair , аб'екты, на якія яны спасылаюцца, розныя. Гэта яскравы прыклад забеспячэння бяспекі тыпаў у Java Generic.

Абмежаванні, што накладаюцца на абагульненыя класы

Важна ведаць, што абагульнення могуць прымяняцца толькі да спасылкавым тыпах, то ёсць перадаваны параметры generic class java аргумент абавязкова павінен быць тыпам класа. Такія простыя тыпы, як, напрыклад, double або long, перадаваць нельга. Іншымі словамі, наступная радок аб'явы класа Pair недапушчальная: Pair obj. Тым не менш дадзенае абмежаванне не ўяўляе сур'ёзнай праблемы, так як у Java для кожнага прымітыўнага тыпу маецца адпаведны клас-абалонка. Строга кажучы, калі ў класе Pair вы хочаце інкапсуляваць цэлалікавых і лагічнае значэнне, автоупаковка зробіць усё за вас: Pair obj = new Pair <> (25, true).

Яшчэ адным сур'ёзным абмежаваннем з'яўляецца немагчымасць стварэння асобніка параметру тыпу. Так, наступны радок выкліча памылку кампіляцыі: T first = new T (). Гэта відавочна, паколькі вы загадзя не ведаеце, ці будзе ў якасці аргументу перадавацца паўнавартасны клас або абстрактны, або зусім інтэрфейс. Тое ж самае тычыцца стварэння масіваў.

абмежаваныя тыпы

Даволі часта ўзнікаюць сітуацыі, калі неабходна абмежаваць пералік тыпаў, якія можна перадаваць у якасці аргументу java generic класу. Дапусцім, што ў нашым класе Pair мы хочам інкапсуляваць выключна лікавыя значэння для далейшых матэматычных аперацый над імі. Для гэтага нам неабходна задаць верхнюю мяжу параметру тыпу. Рэалізуецца гэта пры дапамозе аб'явы суперкласса, спадчыннага усімі аргументамі, якія перадаюцца ў кутніх дужках. Выглядаць гэта будзе наступным чынам: class Pair . Такім спосабам кампілятар пазнае, што замест параметра T можна падстаўляць альбо клас Number альбо адзін з яго падкласаў.

Гэта распаўсюджаны прыём. Такія абмежаванні часта выкарыстоўваюцца для забеспячэння сумяшчальнасці параметраў тыпу ў адным і тым жа класе. Разгледзім прыклад на нашым класе Pair: class Pair . Тут мы паведамляем кампілятара, што тып Т можа быць адвольным, а тып V абавязкова павінен быць альбо тыпам Т, ці адным з яго падкласаў.

Абмежаванне «знізу» адбываецца сапраўды такім жа чынам, але замест слова extends пішацца слова super. Гэта значыць аб'яву class Pair кажа пра тое, што замест Т можа быць падстаўлены альбо ArrayList, альбо любы клас або інтэрфейс, якія ён атрымлівае ў спадчыну.

Generic метады Java і канструктары

У Java абагульнення можна ўжываць не толькі ў дачыненні да класаў, але і метадаў. Так, абагульнены метад можа быць абвешчаны ў звычайным класе.

Як відаць на малюнку вышэй, у аб'яве абагульненага метаду няма нічога складанага. Дастаткова перад вяртаюцца мэтады тыпам паставіць вуглавыя дужкі і паказаць у іх параметры тыпаў.

У выпадку канструктара ўсё робіцца аналагічна:

Вуглавыя дужкі ў гэтым выпадку ставяцца перад назвай канструктара, так як ён не вяртае ніякага значэння. Вынікам працы абедзвюх праграм будзе:

Integer

String

Similar articles

 

 

 

 

Trending Now

 

 

 

 

Newest

Copyright © 2018 be.delachieve.com. Theme powered by WordPress.