Statická data a metody v jazyce Java. Modifikátory v Javě: statické, konečné, abstraktní, synchronizované, přechodné, těkavé. Co je statické

Statický modifikátor v Javě přímo souvisí s třídou, pokud je pole statické, pak patří do třídy, pokud je metoda statická, podobně patří do třídy. Na základě toho můžete přistupovat ke statické metodě nebo poli pomocí názvu třídy. Pokud je například pole count ve třídě Counter statické, můžete k proměnné přistupovat pomocí dotazu jako: Counter.count. Samozřejmě je třeba vzít v úvahu modifikátory přístupu. Například soukromá pole jsou dostupná pouze v rámci třídy, ve které jsou deklarována. Chráněná pole jsou dostupná pro všechny třídy v rámci balíčku ( balík), stejně jako všechny podřízené třídy mimo balíček. Pro více podrobné informace přečtěte si článek „soukromý vs chráněný vs veřejný“. Předpokládejme, že ve třídě Counter existuje statická metoda increment() , jejímž úkolem je zvýšit počet čítačů . Zavolat tato metoda můžete použít volání jako Counter.increment() . Pro přístup ke statickému poli nebo metodě není potřeba vytvářet instanci třídy Counter. To je základní rozdíl mezi statickými a NEstatickými objekty (členy třídy). Důležitá poznámka. Pamatujte, že členové statické třídy přímo patří do třídy, nikoli do její instance. To znamená, že hodnota počtu statické proměnné bude stejná pro všechny objekty typu Counter. V tomto článku se podíváme na základní aspekty používání statického modifikátoru v Javě a také na některé funkce, které vám pomohou pochopit klíčové programovací koncepty.

Co by měl každý programátor vědět o modifikátoru Static v Javě.

V této části se podíváme na základy používání statických metod, polí a tříd. Začněme s proměnnými.

    NEMŮŽETE přistupovat k nestatickým členům třídy v rámci statického kontextu, jako je metoda nebo blok. Kompilace níže uvedeného kódu bude mít za následek chybu:

    public class Counter ( private int count; public static void main (String args) ( System. out. println (count) ; //compile time error ) )

    Toto je jedna z nejčastějších chyb Java programátoři, zejména pro začátečníky. Protože hlavní metoda je statická a proměnná count není, v tomto případě metoda println, uvnitř hlavní metoda vyhodí „Chyba času kompilace“.

    Na rozdíl od lokálních proměnných, statická pole a metody NEJSOU v Javě bezpečné pro vlákna. V praxi jde o jednu z nejčastějších příčin problémů souvisejících s bezpečností vícevláknového programování. Vzhledem k tomu, že každá instance třídy má stejnou kopii statické proměnné, taková proměnná potřebuje ochranu – „uzamčení“ třídou. Při použití statických proměnných se proto ujistěte, že jsou správně synchronizovány, abyste se vyhnuli problémům, jako jsou podmínky závodu.

    Statické metody mají výhodu v aplikaci, protože pro přístup k takovým metodám není nutné pokaždé vytvářet nový objekt. Statická metoda může být volána pomocí typu třídy, ve které jsou metody definovány. Proto podobné metody se ideálně hodí jako tovární metody a užitkové metody. Třída java.lang.Math je skvělým příkladem, ve kterém jsou téměř všechny metody statické, což je stejný důvod, proč jsou třídy obslužných programů v Javě konečné.

    K ostatním důležitý bod je, že nelze přepsat statické metody. Pokud stejnou metodu deklarujete v podtřídě, tzn. metodou se stejným názvem a podpisem, pouze „skryjete“ metodu nadtřídy namísto jejího přepsání. Tento jev je známý jako metody skrývání. To znamená, že při volání statické metody, která je deklarována v rodičích i dětská třída, při kompilaci bude metoda vždy volána na základě typu proměnné. Na rozdíl od přepisování se takové metody nebudou provádět, když je program spuštěn. Podívejme se na příklad:

    třída Vozidlo ( public static void kmToMiles (int km) ( System. out. println ( "Uvnitř rodičovské třídy/statická metoda"); ) ) třída Auto rozšiřuje Vozidlo ( public static void kmToMiles (int km) ( System. out. println ("Uvnitř podřízené třídy / statické metody"

    );

    ) ) public class Demo ( public static void main ( String args ) ( Vehicle v = new Car ( ) ; v. kmToMiles ( 10 ) ; ) )

    Výstup konzole:

    Třídu můžete také deklarovat jako statickou, s výjimkou tříd nejvyšší úroveň. Takové třídy jsou známé jako vnořené statické třídy. statická třída). Jsou užitečné pro reprezentaci vylepšených spojení. Ukázkovým příkladem vnořené statické třídy je HashMap.Entry, která poskytuje datovou strukturu uvnitř HashMap. Stojí za zmínku, že stejně jako každá jiná vnitřní třída jsou vnořené třídy v samostatném souboru .class. Pokud byste tedy ve své hlavní třídě deklarovali pět vnořených tříd, měli byste 6 souborů s příponou .class. Dalším příkladem použití je deklarování vlastního komparátoru, například AgeComparator ve třídě Zaměstnanec.

    Statický modifikátor lze také deklarovat ve statickém bloku, lépe známém jako blok statického inicializátoru, který se spustí při načtení třídy. Pokud takový blok nedeklarujete, Java shromáždí všechna statická pole do jednoho seznamu a spustí jej po načtení třídy. Statický blok však nemůže házet zachycené výjimky, ale může házet nezachycené. V tomto případě se objeví „Chyba inicializátoru výjimky“. V praxi bude jakákoliv výjimka vyvolaná během provádění a inicializace statických polí obalena touto chybou Java. To je také nejvíc společný důvod chyby „No Class Def Found Error“, protože třída nebyla v paměti, když k ní bylo přistupováno.

    Je užitečné vědět, že statické metody jsou vázány v době kompilace, na rozdíl od vazebných virtuálních nebo nestatických metod, které jsou vázány za běhu na skutečný objekt. Proto statické metody nelze v Javě přepsat, protože runtime polymorfismus se na ně nevztahuje. Tento důležité omezení, což je třeba vzít v úvahu při prohlášení metody za statickou. To má smysl pouze tehdy, když neexistuje žádná možnost nebo potřeba přepsat takovou metodu zděděním tříd. Dobrými příklady použití statického modifikátoru jsou tovární metody a užitkové metody. Joshua Bloch nastínil několik výhod použití statické tovární metody oproti konstruktoru ve své knize Effective Java, kterou si musí přečíst každý programátor jazyka.

    Důležitou vlastností statického bloku je inicializace. Statická pole nebo proměnné jsou inicializovány po načtení třídy do paměti. Pořadí inicializace je shora dolů ve stejném pořadí, v jakém jsou popsány zdrojový soubor třída Java. Protože jsou statická pole inicializována způsobem bezpečným pro vlákna, používá se tato vlastnost také k implementaci vzoru Singleton. Pokud z toho či onoho důvodu nepoužíváte seznam Enum jako Singleton , pak je tu pro vás dobrá alternativa. V tomto případě je ale nutné počítat s tím, že se nejedná o „línou“ inicializaci. To znamená, že statické pole bude inicializováno PŘEDTÍM, než o to někdo „požádá“. Pokud je objekt náročný na zdroje nebo se používá zřídka, pak jeho inicializace ve statickém bloku nebude fungovat ve váš prospěch.

    Během serializace, stejně jako přechodné proměnné, nejsou statická pole serializována. Pokud skutečně uložíte nějaká data do statického pole, pak po deserializaci bude nový objekt obsahovat svou primární (výchozí) hodnotu, například pokud bylo statické pole proměnnou zadejte int, pak jeho hodnota po deserializaci bude rovna nule, pokud je typ float 0,0, pokud je typ Object null . Upřímně řečeno, toto je jedna z nejčastějších otázek týkajících se serializace v rozhovorech v Javě. Neukládejte nejdůležitější data o objektu do statického pole!

    A nakonec si promluvme o statickém importu . Tento modifikátor má mnoho společného se standardním příkazem import, ale na rozdíl od něj umožňuje importovat jednoho nebo všechny statické členy třídy. Při importu statických metod k nim lze přistupovat, jako by byly definovány ve stejné třídě, podobně při importu polí k nim můžeme přistupovat bez uvedení názvu třídy. Tato příležitost objevil se v verze Java 1.5 a při správném použití zlepšuje čitelnost kódu. Tento design se nejčastěji vyskytuje v testech JUnit, protože Téměř všichni vývojáři testů používají statické importy pro metody stvrzení, jako je například sustainEquals() a jejich přetížené duplikáty. Pokud není nic jasné, uvítáme další informace.

    To je vše. Všechny výše uvedené body o modifikátoru statický Každý programátor musí znát Javu. Tento článek diskutoval základní informace o statických proměnných, polích, metodách, inicializačních blocích a importech. Včetně některých důležité vlastnosti, jehož znalost je kritická při psaní a porozumění Java programům. Doufám, že každý vývojář zdokonalí své dovednosti v používání statických konceptů, protože... To je velmi důležité pro seriózní programování."

Budeme mluvit o modifikátorech: co jsou modifikátory, rozsahy, modifikátory pro třídy, pole, metody. Myslím, že to nebude nuda.

Modifikátory v Javě jsou klíčová slova, která dávají třídě, poli třídy nebo metodě určité vlastnosti.

K označení viditelnosti třídy jejích metod a polí existují 4 modifikátory přístupu:

  • soukroméčlenové třídy jsou přístupní pouze v rámci třídy;
  • balíček-soukromý nebo výchozí (výchozí)členové třídy jsou vidět uvnitř balení;
  • chráněnýčlenové třídy jsou k dispozici uvnitř balíčku a v podřízených třídách;
  • veřejnostčlenové třídy jsou k dispozici všem.

Pokud si vzpomínáte, na konci, když jsme již importovali třídu Cat, jsme měli stále chybu při kompilaci.

Jde o to, že jsme neurčili žádné modifikátory přístupu k našim polím a metodám a mají výchozí vlastnost (členy třídy jsou viditelné uvnitř balíčku). Abychom opravili chybu kompilace našeho kódu a konečně jej spustili, musíme náš konstruktor a metody zveřejnit. Pak je lze volat z jiných balíčků.

Možná se začnete ptát: k čemu to všechno je? Proč nezviditelnit kód z jakéhokoli balíčku nebo třídy, ale potřebujete omezit přístup? Tyto otázky samy zmizí, až přijde čas na psaní složitých a těžkopádných projektů. Nyní, když píšeme aplikace, jejichž funkčnost je omezena na jednu nebo dvě třídy, zdá se, že nemá smysl cokoliv omezovat.

Představte si, že máte třídu, která zobrazuje objekt určitého produktu. Například auto. Auto může mít cenu. Vytvořili jste pole ceny a mnoho dalších polí, spoustu metod, které jsou zodpovědné za funkčnost. Všechno se zdá být v pořádku. Vaše auto třídy je součástí velkého projektu a všichni jsou šťastní. Ale řekněme, že někdo omylem nebo záměrně vytvořil instanci třídy auta a nastavil zápornou cenu. Může mít produkt zápornou cenu? Toto je velmi primitivní příklad a je nepravděpodobné, že se to stane skutečný život, ale myslím, že myšlenka je jasná. Někdy je potřeba udělit přístup ne přímo, ale prostřednictvím určitých metod. Může se stát, že kód je zodpovědný za funkčnost jiného kódu a vy nechcete, aby někdo měnil a upravoval část vašeho kódu. Pro tento účel existuje omezení přístupu.

Modifikátorem přístupu pro konstruktory, metody a pole může být cokoliv. Třída může být pouze veřejná nebo výchozí a v jednom souboru může být pouze jedna veřejná třída.

Dost už o modifikátorech přístupu. V článku „Objektově orientované programování“ o nich budeme hovořit podrobněji, ale nyní si promluvme o dalších modifikátorech, kterých je mimochodem mnoho.

Nyní přichází modifikátor statický. Lze jej použít před metodou, polem a dokonce i před třídou, když chceme deklarovat vnořenou třídu. V Javě můžete psát třídy uvnitř jiných tříd, a pokud je modifikátor před třídou uvnitř třídy statický, pak se taková třída nazývá vnořená, pokud je jiný modifikátor nebo výchozí, pak se taková třída nazývá interní. O vnořených a vnitřních třídách bude samostatný článek, protože tam není všechno tak jednoduché.

Statický modifikátor před metodou nebo polem označuje, že nepatří do instance dané třídy. Co to pro nás znamená? Když jsme pole třídy nebo metodu deklarovali jako statické, lze je volat bez použití instance třídy. Tedy místo této konstrukce: Kočičí kočka= new Cat(); cat.method(), můžete jednoduše napsat Cat.method(). Za předpokladu, že je metoda deklarována jako statická. Statické proměnné jsou stejné pro všechny objekty třídy. Mají jeden odkaz.

    modifikátory veřejné třídy (

    static int otherStaticField = 5 ;

    public static void myStaticMethod() (

    someField = "Moje pole" ;

    //nonStaticField = ""; chyba kompilace

    //nelze použít nestatická pole

    //ve statických metodách

    public void myNonStaticMethod() (

    otherStaticField = 4 ; //lze použít statická pole

    //v nestatických metodách

    //hlavní metoda má také modifikátor statický

    new Modificators() .myNonStaticMethod() ;

    Modificators.myStaticMethod(); //volání statických metod a polí

    //přes Classname.method

Ještě jedna věc důležitá poznámka O statických modifikátorech je třeba říci jednu věc: statická pole se inicializují při načtení třídy. V různých typech testů Java často najdete následující kód:

Otázka: co bude výstup do konzole? Musíte si pamatovat, že statický blok bude v každém případě vydán jako první. Další bude výchozí blok. Dále se podívejte na obrazovku konzoly:

Další modifikátor, na který se podíváme, bude finále.

Myslím, že slovo finále mluví samo za sebe. Použitím koncového modifikátoru říkáte, že pole nelze měnit, metody nelze přepisovat a třídy nelze dědit (o dědění bude samostatný článek). Tento modifikátor se týká pouze tříd, metod a proměnných (také lokálních proměnných).

O konečném modifikátoru metod a tříd si povíme v článku OOP.

Další budou modifikátory pro začátečníky nebo čtenáře tento cyklusčlánky od nuly nebudou příliš jasné. A i když vám ještě nebudu moci vše vysvětlit (vzhledem k tomu, že neznáte doprovodný materiál), přesto vám doporučuji, abyste se s nimi seznámili. Až přijde čas použít tyto modifikátory, budete již rozumět většině termínů používaných níže.

Modifikátor synchronizované- označuje, že metodu může používat vždy pouze jedno vlákno. I když vám to nemusí nic říkat, užitečnost tohoto modifikátoru uvidíme, až budeme studovat multithreading.

Modifikátor přechodný— označuje, že určité pole by mělo být během serializace objektu ignorováno. Tato pole zpravidla ukládají mezihodnoty.

Modifikátor nestálý- používá se pro multithreading. Když bude pole s nestálým modifikátorem používáno a upravováno více vlákny, tento modifikátor zajišťuje, že pole bude postupně modifikováno a nedojde k žádné záměně.

Modifikátor rodák před deklarováním metody označuje, že metoda je napsána v jiném programovacím jazyce. Obvykle v jazyce C.

Modifikátor strictfp— Zajišťuje provádění operací s čísly typu float a double (s plovoucí desetinnou čárkou) standard IEEE 754. Nebo jednodušeji zaručuje, že v rámci metody budou výsledky výpočtu stejné na všech platformách.

O modifikátoru jsem ještě nemluvil abstraktní. Řeknu vám o tom krátce, protože bez znalosti základů orientované programování Nevidím smysl se o něm bavit.

Třída, která má modifikátor abstract, nemůže vytvořit instanci. Jeho jediným účelem je rozšíření. Abstraktní třída může obsahovat jak abstraktní metody, tak běžné.

Více si o abstraktním modifikátoru povíme v článku OOP.

Zde můžeme dokončit článek o modifikátorech. Moc se o nich neřeklo. Ale to je dáno tím, že ještě nemáme koncepty OOP. V průběhu několika článků si rozšíříme znalosti o modifikátorech a doplníme mezery.

Statická metoda je fragment programu, kterému jsou přiřazeny nějaké jedinečné jméno, a které lze pod tímto jménem volat z jiných částí programu. V okamžiku, kdy dojde k volání, jsou provedeny akce uvedené uvnitř metody (v jejím popisu nebo těle).
V objektově orientovaném programování je hlavním úkolem metod změnit aktuální stav objektu, ale pokud ještě nejsou objekty v programu používány, lze metody již zavádět. Metoda, která je popsána uvnitř třídy, ale je volána bez aplikace konkrétní objekt tato třída se nazývá statická.

Kromě výše uvedeného názvu a popisu má metoda řadu dalších charakteristik:

  1. Sada modifikátorů.
  2. Typ návratové hodnoty.
  3. Sada argumentů (parametrů).

Modifikátory metod

Chcete-li vytvořit statickou metodu, musíte před jejím názvem zadat modifikátor static. Pokud se tak nestane, lze metodu volat pouze v aplikaci na konkrétní objekt této třídy (bude nestatický).

Veřejný modifikátor je zodpovědný za úroveň přístupu k popsané metodě. Úrovně lze zadat místo veřejné soukromý přístup nebo chránit, nebo nelze nic specifikovat, pak se použije výchozí úroveň přístupu.

S úrovněmi přístupu se podrobněji seznámíme, až si vytvoříme vlastní třídy, ale prozatím podotýkáme, že výchozí přístup umožňuje přístup k metodě z libovolné části balíčku, ve kterém je metoda popsána. A veřejná úroveň umožňuje přístup k metodě odkudkoli. Včetně z jiných balíčků a programů.

Hlavní metoda musí mít úroveň veřejného přístupu právě proto, že k ní přistupuje virtuální java stroj, není součástí žádného balení.

Kromě toho existují další modifikátory, které například umožňují regulovat činnost metod při paralelních (vícevláknových) výpočtech.

Návratový typ

Metody v Javě lze rozdělit do dvou skupin: funkce a procedury. Do první skupiny patří metody, které jsou velmi podobné funkcím v matematickém smyslu. Takové metody v důsledku své práce vracejí nějaký konkrétní výsledek na místo v programu, ze kterého byly volány. stávající typ, to znamená, že to může být celé číslo nebo skutečné číslo nebo logická hodnota (int, double, boolean), pole (odkaz na něj), objekt (odkaz na něj). Návratová hodnota musí být přiřazena proměnné vhodný typ nebo předán nějaké jiné metodě jako argument.

Na rozdíl od funkcí, metody procedurálního typu produkují nějaký druh užitečné akce, ale neposkytují úplný výsledek, který by mohl být vyjádřen v jedné konkrétní hodnotě nebo objektu.

Dvojité r = Math.random(); /* náhodné odkazuje na funkce */ System.out.println(r); /* println odkazuje na procedury */

Pokud bychom vytvořili metodu, která by stejně jako println vytiskla text na obrazovku, ale zároveň spočítala počet mezer v textu a vrátila tento výsledek, dostali bychom funkci. V tomto případě by funkce pokračovala v provádění užitečných akcí charakteristické pro proceduru println. Funkce je tedy univerzálnější než procedura, ale není vždy nezbytná.

Při vytváření metody je prvním krokem určení, zda se bude jednat o funkci nebo proceduru. Pro mezivýpočty se obvykle používají funkce. Procedury mohou být také vhodné pro zkrácení podobných fragmentů kódu.

Za modifikátory, ale také vlevo od názvu metody, je uveden typ hodnoty, kterou vrací (pokud je metoda funkcí, například: int nebo double) nebo slovo void (pokud je metoda procedura) .

Pokud je metoda funkcí, pak musí obsahovat návratový příkaz za nímž je, oddělený mezerou, uveden výraz, jehož hodnota by měla být vrácena jako výsledek metody.

Všechny příkazy uvedené v popisu metody po returnu již nebudou provedeny return bez argumentu lze použít uvnitř procedur. Jednoduše ukončí proceduru před plánem (obdoba přerušení pro smyčku).

Argumenty (parametry)

Při volání metody jí lze z hlavního programu předat sadu určitých hodnot. Aby bylo možné metodu naučit je přijímat (a zpracovávat je uvnitř metody), musí být dvojice formuláře uvedeny v závorkách za názvem metody: typ_argumentu název_argumentu oddělené čárkami.

Poté při volání metody bude možné zadat sadu hodnot odpovídajících typům popsaným v argumentech.

Hodnoty, které jsou předány metodě v době volání, se nazývají skutečné parametry a názvy argumentů, které se objevují v popisu metody, se nazývají formální parametry.

Každý formální parametr je lokální proměnná uvnitř metody, to znamená, že není dostupný mimo metodu (mimo její popisný blok). Při volání metody se skutečná hodnota zkopíruje do formálního parametru.

Zejména to znamená, že předáním libovolné proměnné základní typ jako parametr k metodě, když je volána, nebudeme moci změnit hodnotu této proměnné v hlavním programu. Pokud je nějaký objekt nebo pole předán metodě prostřednictvím argumentu, pak se do metody zkopíruje pouze odkaz na objekt nebo pole (tj. jejich adresa v paměti). Akce, které provádíme s polem nebo objektem uvnitř metody, ovlivní stav tohoto pole nebo objektu v hlavním programu i poté, co metoda dokončí svou práci. Uvnitř metody jsme přistupovali na stejnou adresu a pracovali se stejnými daty v paměti, která byla k dispozici v hlavním programu.

Pokud je název skutečného parametru stejný jako formální parametr, pak to nezpůsobuje žádný problém: uvnitř metody je lokální proměnná, do které se při volání zkopíruje hodnota stejnojmenné globální proměnné. Přístupem k tomuto názvu uvnitř metody skončíme s lokální proměnnou a nebudeme se moci dostat do globální.

Popis metody

Metoda musí být popsána uvnitř třídy, ale jedna metoda není popsána uvnitř druhé, to znamená, že metoda musí být vnořena přímo do bloku třídy.

Obecné schéma pro popis metody:

Modifikátory return_value_type název_metody (formální argumenty) ( // akce prováděné metodou // možná, return )

Tradičně musí název metody začínat malým písmenem. Pokud se skládá z několika slov, každé následující slovo začíná na velké písmeno. Název pro metodu je zvolen tak, aby bylo jasné, co dělá.

Podívejme se na několik příkladů:

Public static double kvadk (double) ( double t; t = Math.pow(a, 0,5); return t; )

Nyní uvnitř hlavní metody můžeme použít naši metodu. Například takto:

Int a = 25; System.out.println(kvadk(a)); // 5.0 System.out.println(a) // 25

Při předávání skutečných parametrů metodě dochází k autocastingu. Pokud skutečný argument neodpovídá formálnímu typu, Java se pokusí přetypovat skutečný argument na více univerzální typ(PROTI v tomto případě int byl obsazen na dvojnásobek).

Přetížení metody

Signatura metody je kombinací jejího názvu a sady formálních parametrů.
Java umožňuje vytvářet více metod se stejnými názvy, ale různými podpisy. Vytvoření metody se stejným názvem, ale s jinou sadou parametrů se nazývá přetěžování. Java na základě skutečných parametrů určuje, která přetížená metoda se má při volání provést.

Void pr(double a) ( System.out.println(a); ) void pr (String a) ( System.out.println(a); ) void pr(int a) ( for (int i=0; i

Příklad použití metody.

Int a = 5; int m = (1, 2, 8, 3) Řetězec s = "Svět"; pr (a) //původní metoda funguje pr (a+s); // Svět 5, první přetížení běží pr (m); // 1 2 8 3 pr (m+a); // chyba

Proměnná a není typu double, ale je zpracována původní metodou, protože je možné automatické přetypování z int na double. Opačným směrem to nejde. Pokud by metoda měla argument typu int, pak by nemohla vypisovat reálná čísla.

Přetěžování metod implementuje tak důležitou vlastnost v programování, jako je polymorfismus. Polymorfní je softwarový kód, který je spojen s jedním společným názvem, ale má různé implementace. Která implementace bude fungovat se vybírá na základě kontextu, ve kterém bylo jméno zmíněno. Konkrétně u metod jsou jejich přetížení polymorfní a výběr spustitelného přetížení probíhá podle parametrů.

Polymorfismus: jedno jméno, mnoho podob.

Příklady použití metod

Následující program vyhledá a zobrazí všechny prvočíselné netriviální dělitele čísla zadaného uživatelem z klávesnice, počínaje největším dělitelem, nebo hlásí, že zadané číslo je prvočíslo.

Importovat java.util.Scanner; public class Main ( public static boolean isPrime(int n) ( for(int i = 2; i<= Math.sqrt(n) ; i++) { if(n%i == 0) { return false; } } return true; } public static void main(String args) { Scanner sc = new Scanner(System.in); System.out.print("Введите натуральное число: "); if(sc.hasNextInt()) { int u = sc.nextInt(); if(u >0) ( if(isPrime(u)) ( System.out.println("Zadali jste prvočíslo"); ) else ( System.out.print("Prvočinitele čísla: "); for(int i = (int) Math.sqrt(u i >= 2 i--) ( if(u%i == 0 && isPrime(i)) ( System.out.print(i+" "); ) ) System; .out.println ( ) ) else ( System.out.println("Nezadali jste kladné číslo"); ) ) else ( System.out.println("Nezadali jste celé číslo"); ) ) )

V následujícím příkladu bude z důvodu přetížení vytvořeno několik metod stejného názvu.

První verze metody jednoduše přeloží řetězec, tj. bude to ve skutečnosti kratší synonymum pro vestavěnou metodu System.out.println(). Tato možnost nebude mít žádné parametry.

Druhá varianta metody (její první přetížení) kontroluje, zda má numerický argument zlomková část, pokud tam není, pak se argument převede na celá čísla a zobrazí se na obrazovce bez nulové zlomkové části (3 místo 3.0). Této metodě lze jako jediný argument předat nejen proměnné typu double, ale také proměnné jakéhokoli jiného typu, u kterých je možné automatické přetypování na zdvojnásobení (například libovolné celočíselné proměnné).

Třetí metoda s jedním parametrem jednoduše zavolá čtvrtou metodu a předá výsledné pole jako parametry a také mezeru jako druhý parametr. Upozorňujeme, že voláme metodu, která bude popsána dále v programu, což je zcela přijatelné.

Čtvrtá metoda vydává číselné pole, které již zpracovává každý prvek stávající metoda. Po každém zobrazeném prvku se přidá oddělovač předaný v parametru.

Public class Main ( public static void pr() ( System.out.println(); ) public static void pr(double d) ( if((int)d == d) ( System.out.print((int)d ) else ( System.out.print(d); ) ) public static void pr(double m) ( pr(m, " "); ) public static void pr(double m, String s) ( for(int i) = 0;< m.length; i++) { pr(m[i]); System.out.print(s); } } public static void main(String args) { double arrn = {1, 2.71, 3.14, 15, -5, 92, 0.5}; double p = 3.0; int k = 13; pr(p); // вывод числа, без дробной части при возможности pr(); // переводит строку pr(arrn); // вывод číselné pole na řádek pr(); // přeloží řetězec pr(arrn,", "); // výstup číselného pole na řádek oddělený čárkami pr(); // přeloží řetězec pr(k); // výstup celého čísla přes autocast ) )

V důsledku běhu programu se na obrazovce zobrazí následující:

3 1 2.71 3.14 15 -5 92 0.5 1, 2.71, 3.14, 15, -5, 92, 0.5, 1

Úkoly

  1. Vytvořte statickou metodu, která bude mít dva celočíselné parametry aab, a vrátí náhodné celé číslo ze segmentu jako jeho hodnotu. Pomocí této metody vyplňte pole 20 celých čísel a zobrazte je na obrazovce.
  2. Vytvořte metodu, která zobrazí zadané pole na obrazovce jako řetězec. Pomocí vytvořené metody a metody z předchozí úlohy vyplňte 5 polí po 10 prvcích náhodná čísla a zobrazit všech 5 polí na obrazovce, každé na samostatném řádku.
  3. Vytvořte metodu, která seřadí zadané pole ve vzestupném pořadí jakýmkoli způsobem, který znáte.
  4. Pole ukládá 7 explicitně specifikovaných textové řetězce. Napište program, který bude třídit a zobrazovat řetězce abecední pořadí. Pokud byly například uvedeny následující řádky:
Puškin Lermontov Nekrasov Tolstoj L. N. Tolstoj A. N. Yesenin Paustovsky

Program by měl zobrazovat:

Yesenin Lermontov Nekrasov Paustovsky Puškin Tolstoj A. N. Tolstoj L. N.

Tip: Nejprve musíte vytvořit metodu, která nastaví vztah řazení pro dva řetězce předané metodě jako argumenty.

Rekurze

Rekurze je metoda (funkce), která sama sebe volá ve svém těle.

Podívejme se na příklad – výpočet faktoriálu. K výpočtu n! stačí znát a vynásobit (n-1)! a n.

Vytvořme metodu, která implementuje popsanou metodu.

Statický int fakt (int n) ( if (n==1) ( return 1; ) else if (n==2) ( return 2; ) else ( return fact(n-1) * n; ) )

Zadaná metoda vypočítá faktoriál přirozeného čísla.

Uvažujme příklad, který vypočítá n-té Fibonacciho číslo pomocí rekurze.

Připomeňme si, jak vypadají první prvky této série: 1 1 2 3 5 8 13 ...

Statické int fib (int n) ( if (n==1 || n == 2) ( návrat 1; ) návrat fib (n-2) + fib (n-1); )

Všimněte si, že v této metodě není druhý návrat umístěn do bloku else pro první podmíněný operátor. To je přípustné, protože pokud je podmínka splněna a je spuštěn první návrat, pak provádění programu dosáhne druhého návratu, pokud podmínka splněna není;

Rekurzivní výpočty často vedou k nutnosti opakovat stejné akce, což výrazně zpomaluje program.

Úkoly

  1. Experimentálně zjistěte, od kterého prvku Fibonacciho posloupnosti se výpočet pomocí rekurze stává nepřijatelným (trvá déle než minutu).
  2. Vytvořte hybridní metodu, která pro malé n vypočítá n-té Fibonacciho číslo pomocí rekurze a pro hodnoty vyšší než prahová hodnota n, kterou jste našli v předchozím problému, vypočítá n-té Fibonacciho číslo pomocí iteračního algoritmu (smyčka, ve které hodnoty dvou předchozích prvků sekvence).
  3. Spočítejte, kolikrát by bylo nutné přepočítat čtvrtý prvek Fibonacciho posloupnosti, abyste vypočítali patnáctý prvek.

Zásobník hovorů

V obecný případ PROTI aktuální okamžik v jeden okamžik lze provést pouze jeden jedinou metodou z celého programu. To znamená, že pokud metoda A je navržena tak, že ve svém těle volá metodu b a on sám A zavolal hlavní, poté při spuštění programu bude řízení nejprve přeneseno na metodu hlavní, pak metoda A, pak metoda b. Metoda b vrátí výsledek a kontrolu A, A vrátí výsledek kontroly do hlavní a teprve potom budou popraveni základní příkazy specifikované v metodě hlavní na zbývajících linkách po hovoru A.

Celá hierarchie (kdo komu volal) je uložena ve speciální paměťové oblasti zvané zásobník hovorů. Prvky se do tohoto paměťového fragmentu přidávají podle následujícího principu: jako první musí být načten naposledy přidaný prvek. Když metoda funguje b, ukazuje se, že pod ním na zásobníku jsou metody A a způsob hlavní.

Z tohoto důvodu existuje nebezpečí přetečení zásobníku volání během procesu rekurze.

Dochází k tzv. komplexní rekurzi, při které se metoda A volá metodu b, b příčiny S, A S příčiny A.

2010, Alexej Nikolajevič Kostin. Oddělení TIDM Matematická fakulta MPGU.

Co je statické

V některých případech je žádoucí definovat člena třídy, který bude použit nezávisle na jakémkoli objektu této třídy. Obvykle by měl být člen třídy přístupný pouze ve spojení s objektem jeho třídy. Je však možné vytvořit člen třídy, který lze použít samostatně, bez odkazu na konkrétní instance. Chcete-li vytvořit takový člen, musíte na začátek jeho deklarace umístit klíčové slovo static. Když je člen třídy deklarován jako statický, je přístupný před vytvořením jakýchkoli objektů jeho třídy a bez odkazu na jakýkoli objekt. Metody i proměnné mohou být deklarovány jako statické. Nejčastější příklad statický člen- metoda main(). Tato metoda je deklarována jako statická, protože musí být deklarována před vytvořením jakýchkoli objektů.

Proměnné instance deklarované jako statické jsou v podstatě globální proměnné. Při deklaraci objektů jejich třídy program nevytváří žádné kopie statické proměnné. Místo toho všechny instance třídy sdílejí stejnou statickou proměnnou.

Metody deklarované jako statické podléhají řadě omezení.

  • Mohou volat pouze jiné statické metody.
  • Měli by přistupovat pouze ke statickým proměnným.
  • Nemohou žádným způsobem odkazovat na členy typu this nebo super. ( Klíčové slovo super souvisí s dědictvím a je zahrnuto v další kapitole.)

Pokud pro inicializaci typové proměnné static potřebuje provádět výpočty, můžete deklarovat statický blok, který bude proveden pouze jednou při prvním načtení třídy. Následující příklad ukazuje třídu, která obsahuje statickou metodu, několik statických proměnných a statický inicializační blok:

// Demonstrace statických proměnných, metod a bloků.
třída UseStatic(
statické int a = 3;
statický int b;
static void meth(int x) (
System.out.println("x = " + x) ;
System.out.println("a = " + a);
System.out.println("b = " + b) ;
}
statický (
System.out.println("Statický blok inicializován.");
b = a* 4;
}

meth(42);
}
}

Ihned po načtení třídy UseStatic program provede všechny statické příkazy. Nejprve je hodnota a nastavena na 3, poté program provede statický blok, který vypíše zprávu, a poté inicializuje proměnnou b s hodnotou a*4 nebo 12. Program poté zavolá metodu main(), která volá metodu meth() a předává hodnotu x 42. Tři příkazy println() odkazují dvě statické proměnné aab na lokální proměnnou x.

Výstup tohoto programu vypadá takto:

Statický blok inicializován, x = 42 a = 3 b = 12

Mimo třídu, ve které jsou definovány, lze statické metody a proměnné používat nezávisle na jakémkoli objektu. Chcete-li to provést, jednoduše zadejte název jejich třídy a poté operaci tečka. Pokud je například třeba volat metodu typu static z místa mimo její třídu, lze to provést pomocí následujícího obecného formuláře:

class_name.method()

Zde název_třídy je název třídy, ve které je deklarována metoda typu static. Jak vidíte, tento formát je podobný tomu, který se používá k volání nestatických metod prostřednictvím objektových referenčních proměnných. Ke statické proměnné se přistupuje podobným způsobem – přes tečkový operátor za názvem třídy. Takto Java implementuje spravované verze globálních metod a proměnných.

Uveďme příklad. V rámci metody main() se ke statické metodě callme() a statické proměnné b přistupuje pomocí jejich názvu třídy StaticDemo.

třída StaticDemo (
statické int a = 42;
statické int b = 99;
static void callme() (
System.out.println("a = " + a);
}
}
class StaticByName(
public static void main(String args) (
StaticDemo.callme();
System.out.println("b = " + StaticDemo.b);
}
}

Výstup tohoto programu vypadá takto.




Nahoru