O programování 08 - Jak v Javě předat metodu, která bude mít různé parametry
V minulém díle jsem řešil, jak předat v Javě metodu jako parametr, což lze díky funkčnímu interface. Zajímalo mě však ještě, jak předat metodu, která bude mít různé parametry. Metoda, která má různé typy parametrů (ale stejnou aritu) není problém, což ukazuje následující příklad, v němž jednou předávám metodu pro List Integerů a ve druhém případě List Stringů. (Pro naše účely se oprosťme od implementace metody pro String, která nedělá nic smysluplného.)
Function<List<Integer>, List<Integer>> methodListInteger = (List<Integer> inputList) -> {
List<Integer> outputList = new ArrayList<>(inputList.size());
for (Integer integer : inputList) {
outputList.add(++integer);
}
return outputList;
};
Function<List<String>, List<Integer>> methodListString = (List<String> inputList) -> {
List<Integer> outputList = new ArrayList<>(inputList.size());
for (String string : inputList) {
outputList.add(Integer.parseInt(string) + 1);
}
return outputList;
};
final List<Integer> outputList1 = methodListInteger.apply(new ArrayList<>());
final List<Integer> outputList2 = methodListString.apply(new ArrayList<>());
Tento zápis se mi celkem líbí, protože můžu celkem elegantně řešit různé transformace. V Javě jsem totiž omezen silnou typovou kontrolou, takže musím používat interface, dědičnost a generiky. Zmíněný Javový aparát bych ale stejně musel používat, pokud bych výše uvedený příklad chtěl používat k něčemu rozumnému, protože kromě metody musím předat i vstupní a výstupní parametry odpovídajícího typu. Jiným slovy, hledáme různě více či méně chytré způsoby jak obejít silnou typovost v Javě - což jde proti duchu jazyka, takže v tom zatím nebudu pokračovat.
Ještě před koncem těchto úvah se zmíním o další úrovni problému a to o případu metod s různým počtem parametrů. K této potřebě mě vedl praktický problém, kdy jsem mapoval různé beany na sebe. Napsal jsem univerzální mapper, který měl v 90% případů na vstupu jednu beanu a na výstupu druhou. Ovšem občas jsem potřeboval mapperu předat parametr navíc, sice to byl asi špatný návrh, protože jsme se toho během refactoringu zbavili, ale někdy to může být opravdu požadováno.
Řešil jsem to pomocí proměnného počtu parametrů (Object... beans) v metodě, což vůbec není dobré řešení. Musím totiž vědět, že tento konkrétní případ volání potřebuje více parametrů a jaké parametry jsou očekávány na vstupu. A zkontrolovat správnost i počet paramterů jsem schopen až v runtime, což degraduje silnou typovost Javy.
A tímto svoji úvahu na téma metody s různými parametry končím - vlastně to nepotřebuji a neodpovídá to ani principům Javy.
- O programování 01 - Úvod
- O programování 02 - Efektivita funkcionálního přístupu v Java 8
- O programování 03 - Přehlednost funkcionálního zápisu v Java 8
- O programování 04 - Java Microbenchmark Harness
- O programování 05 - Další varianty Javovské implementace foreach
- O programování 06 - Návrhové vzory - síla i slabina Javy
- O programování 07 - Funkce jako argument aneb od factory k lambdě v Javě
- O programování 09 - Pokročilé využití streamů a funkcionálního přístupu v Java 8
- O programování 10 - Java a inspirace v Ruby
- O programování 11 - Minimalistické programy a Java
- O programování 12 - Paralelní implementace násobení matic v Java - úvod