V následujícím textu budou často používané pojmy, které je nutno pro srozumtelnost specifikovat:
1 2 3 4 5 | <T> // typovy parametr <T> void metoda(T) // metoda s typovym parametrem void metoda(List<String>) // metoda s generickym parametrem List<T> a // generický datový typ s typovym parametrem void metoda(String...a) // metoda s proměnlivým parametrem |
Podle popisu jazyka Java(1) se propojení volání (resp. reference) metody a deklarace metody provádí ve třech fázích. Pokud propojení neuspěje v jedné fázi pokračuje se další. Nepovede-li se propojení ve třetí fázi, je nahlášena chyba při překladu. V první řadě se však detekuje, zda je metoda potenciálně propojitelná. Tedy vyhledá se množina aplikovatelných deklarací metod. Tyto potenciální metody musí splňovat všechny následující kritéria:
- identické názvy reference a deklarace metody,
- blok kódu volající metodu musí mít patřičný přístup k deklaraci metody,
- jestliže má metoda n parametrů se speciálním parametrem určujícím proměnlivý počet parametrů (variable arity method) , musí mít reference na metodu více nebo rovno n-1 parametrů
- jestliže nemá metoda tento speciální parametr a má n parametrů, potom musí mít reference metody právě n parametrů,
- jestliže je v referenci metody použitý explicitní typový argument a metoda je generická, potom musí být počet typových parametrů roven počtu typových parametrů metody.
V první fázi propojování reference metody s deklaraci vycházíme z množiny potenciálně aplikovatelných metod. Zde se postup větví podle toho, zda je metoda generická, či ne.
Jestliže se jedná o generickou metodu je nutno kontrolovat , zda odpovídají datové typy parametru, které nemají generický datový typ a dále zda lze generický typ navázat na datový typ z volání metody.
Jestliže se naopak nejedná o generickou metodu, je propojení možné, pokud jsou parametry referencované metody stejného datového typu, jako deklarované metody nebo podtypu. Další možností je, že jsou datové typy konvertovatelné.
Jestliže nejsou podmínky první fáze splněny s žádnou deklarací, pokračuje se druhou fází propojení reference metody s deklarací.
Druhá fáze
Tato fáze se na rozdíl od první pokouší o explicitní konverzi parametrů, pokud nejsou generické. V případě parametrů s generickým datovým typem je postup stejný
Třetí fáze
Poslední fáze spočívá v propojování metod, které mají proměnlivý počet parametrů. Detekce propojení je založena na předchozích fázích. Navíc je mezi podmínkami možnost výskytu tohoto parametru umožňující proměnlivý počet parametrů.
V případě parametrů s negenerickým datovým typem je potřeba při vytváření dočasných vrcholů metod v grafu vytvořit tento uzel s již konvertovanými typy. Tuto možnost nám poskytuje knihovna Procyon, díky které při volání metody můžeme získat výsledný datový typ konverze typu parametru. Pokud později narazíme na deklaraci metody, může již porovnání probíhat pomocí uložených datových typů. Pokud bude vytváření vrcholů probíhat v opačném pořadí, opět bude potřeba srovnávat parametry vrcholu deklarované metody s konečným datovým typem parametrů referencované metody.
Neboť je možné za typové parametry dosadit jakýkoliv typ, bude při hledání shody metod porovnání libovolného typu s typovým parametrem vždy označováno jako shodné. Detekce špatného přiřazení typu do parametru se nebude provádět. Předpokládá se, že kompilátor provedl bezchybný převod do bajtkódu.
Protože knihovna Procyon pracuje s proměnlivým parametrem jako s polem a v případě volání metody s tímto proměnlivým parametrem dokáže rovnou tvrdit, že je poslední parametr pole, je práce s voláním metody stejná, jakoby se na poslední pozici vyskytovalo pole odpovídajícího datového typu. Tedy práce s touto metodou se nebude nijak lišit oproti práce s jinými metodami.
Shrnutí
Propojení volané metody s deklarací metody bude probíhat na základě následujících bodů:
- shodné jmého metody,
- shodný počet parametrů,
- shodný datový typ všech parametrů,
- typový parametr bude označen jako shodný s libovolným typem,
- generické parametry se shodným hlavním typem (např.: List, Map) , ale rozdílnými typovými parametry budou taktéž označeny jako shodné.
Zdroje:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2