Statické metódy a ich úskalia v Jave
V nasledovnom článku sa bližšie pozrieme na prekrývanie statických metód a na dôsledky, ktoré z toho vyplývajú. Nie tak dávno som bol pred problémom refaktoringu DB objektov. Aplikácia stará viac ako 7 rokov bola vyvíjaná ľuďmi čo sa na tom učili. Nikoho isto neprekvapí, že z času na čas je v takýchto aplikáciách potrebné urobiť trošku prievan a zrefaktorovať kód, pretože pokračovanie znamená len kopenie ďalších problémov.
Cieľom bolo znížiť duplicitu kódu, oddeliť kód špecifický pre objekty, od zdieľaného kódu, vyčlenenie kódu do statických metód a tak ďalej. Pri poslednom menovanom som narazil na niektoré úskalia pri definovaní a využívaní statických metód. O tých by som rád napísal v nasledovnom príspevku.
Možnosti statických metód
Statické metódy najčastejšie využívame ako pomocné metódy, ktoré všetky potrebné parametre dostanú na vstupe a po spracovaní vrátia výsledok. Väčšinou sú to rôzne formátovacie a kontrolné metódy. Tie sa často spájajú a vytvárajú tak pomocné triedy.
Dajú sa statické metódy prepísať?
Nie, avšak sa dajú prekryť. Ich funkčnosť potom závisí od toho ako sú volané neskôr.
Použitie
Definujme si nasledovné triedy:
Abst.java
abstract public class Abst {
public static String getName() {
return „Abstraktna trieda“;
}
public String getText() {
return getName();
}
}
A.java
public class A extends Abst{
public static String getName() {
return „A“;
}
}
B.java
public class B extends A{
public static String getName() {
return „B“;
}
}
C.java
public class C extends B{
public static String getName() {
return „C“;
}
}
Vytvorili sme triedy, ktoré vždy prekrývajú telo statickej metódy svojho predka. Prekrývanie statických metód sa neodporúča, nakoľko ich chovanie nemusí vždy byť vždy také ako by sme očakávali od prepisovaných metód. Osobne som názoru, že ich použitie vytvára zmätok v kóde a poukazuje na zlý návrh.
Napríklad Eclipse ani nedovolí vygenerovať taký kód, kedže sa nejedná o prepisovanie, ale len o prekrytie. Takže tuto obludnosť musíme napísať sami. Ešte by som dodal, že nad takto definovanou statickou metódou nie je možné použiť anotáciu „@Override“.
Pre Eclipse užívateľov
Volaním Eclipse funkcie „Quick Type Hierarchy“ (pri štandardnom nastavení klávesnice, CTRL-T) sa hierarchicky zobrazuje, v ktorých triedach potomkov a predkov je métodá prepisovaná, v prípade statickej metódy prekrytá.
Testovanie
Pri priamom volaní našich statických metód funguje všetko ako by sme čakali.
Abst.getName() : Abstraktna trieda
A.getName() : A
C.getName() : C
Ako ovplyvní výsledok volanie z inštancii tried?
Abst a = new C();
a.getName(): Abstraktna trieda
a.getText(): Abstraktna trieda
Toto je štandardné očakávanie. Nikto nepredpokladá, že niekto neskôr prekrýva statickú metódu definovanú v abstraktnej triede. Avšak my prekrývame a pri zmene bázovej triedy následne dostaneme iný výsledok.
B b = new C();
b.getName(): B
b.getText(): Abstraktna trieda
Vidíme, že volanie statickej metódy volalo metódu bázovej triedy, v tomto prípade triedy B. Ďalšia záludnosť spočíva v prípade modifikácie triedy A prepísaním metódy getText() nasledovným kódom:
@Override
public String getText() {
return getName();
}
kde dostaneme pri volaní vyššie uvedených príkladov nasledovné výsledky
Abst a = new C();
a.getName(): Abstraktna trieda
a.getText(): A
B b = new C();
b.getName(): B
b.getText(): A
Dá sa vždy zavolať tá „správna“ prekrytá metóda?
Áno, dá. Avšak tú správnu statickú metódu je potrebné zavolať pomocou reflexie.
Do abstraktnej triedy Abst pridáme nasledovný kód:
public String getNameDynamic() {
try {
return (String) this.getClass().getMethod(„getName“).invoke(this);
} catch (Exception e) {
// v normalnom kode RuntimeException nepouzivat!
// toto je len pre testovacie ucely
throw new RuntimeException(e);
}
}
Vďaka tomu sa vždy zavolá správna statická metóda, nezávislá od bázovej triedy.
A výsledok:
Abst a = new C();
B b = new C();
a.getNameDynamic(): C
b.getNameDynamic(): C
Záver
Na týchto príkladoch som chcel poukázať na úskalia pri prekrývaní statických metód. Ako som už písal vyššie, samotné prekrývanie statických metód u tried potomkov považujem za zlý prístup a zlý návrh samotného programu. Takéto riešenie problému by nemalo byť použité vôbec.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Nepodceňte UX na vašem webu: Proč na něm záleží?
10. dubna 2024 -
Fandíme českým sportovcům a rozdáváme hosting ZDARMA!
26. července 2024 -
Od iPhonu po Android: Ultra HDR přináší nový standard fotografií
1. listopadu 2024
Nejnovější
-
Jak rozšířit úložiště Macu za pětinovou cenu?
16. prosince 2024 -
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024