
Java pro LotusScriptové programátory 4. 
Jan Krejcárek, 03.24.2010
|
Kategorie: Články\Lotus Notes
Přetypování je způsob, jakým programu říci, aby s proměnnou určitého typu pracoval jako s proměnnou jiného typu. Při práci s Notesovými objekty v Javě se s přetypováním setkáme poměrně často např. při načítání obsahu polí nebo při práci s hodnotami ve sloupcích v pohledech. Při přetypování musí být oba typy nějakým způsobem aspoň vzdáleně spřízněné, nelze přetypovat číslo na řetězec, to už by byla konverze.
V jedné z předchozích částí bylo zmíněno, že třída Vector je rostoucí kolekce prvků - není třeba se starat, kolik toho do Vectoru sypeme, jeho velikost roste podle potřeby. Důležité je, že prvky, které se do Vectoru vkládají, mohou být libovolného typu (text, číslo, instance třídy Dělo nebo Bagr). Aby toto bylo zajištěno, přijímá metoda Vector.add() jako parametr instanci třídy java.lang.Object. Tato třída je prapředkem všech objektů v Javě. V objektově orientovaném programování platí, že potomek může zastoupit předka. Máme-li tedy proměnnou typu String, můžeme ji použít všude tam, kde je vyžadována třída Object (obráceně už to nejde).
Díky tomuto principu je tedy možné vložit do Vectoru instanci jakékoliv třídy. Když je později potřeba z Vectoru načíst vše co jsme do něj vložili, získáme ale instance typu Object. Protože s prvky ve Vectoru chceme zase pracovat jako s Dělem nebo Bagrem, je třeba je přetypovat.
Syntaxe přetypování
Přetypování se v kódu provádí jednoduchým způsobem:
Object obj = v.get(0); //načte z Vectoru prvek s určeným indexem
String text = (String) obj; //přetypování proměnné Ojbect na proměnnou typu String
nebo úsporněji:
String text = (String) v.get(0);
Typ, na který se bude přetypovávat se prostě uvede v závorkách před proměnnou nebo volanou funkcí (v tom případě je přetypována návratová hodnota).
Co se může pokazit
Přetypování selže, pokud proměnná není typu, na který ji chceme přetypovat. V takovém připadě je za chodu vyhozena výjimka ClassCastException.
Bránit se tomu lze tak, že ještě před přetypováním se ujistíme, že proměnná je skutečně toho typu, který čekáme. Test se provede pomocí klíčového slova instanceof takto:
Object obj = v.get(0); if (obj instanceof String) { String text = (String) obj; //zbytek kódu }
Tento test je nejspíše zbytečný, pokud si Vector vytváříme a plníme sami nebo když přesně známe typy objektů vložených do Vectoru.
Použití Vectoru v Notesovém API
Notesové API používá Vector na mnoha místech. Mezi metody, které vrací Vector patří Session.getUserGroupNameList(), Database.getAgents(), Item.getValues(), Document.getItemValue(), ACLEntry.getRoles(), Database.getViews() a další. Pokud chceme pracovat s objekty do Vectoru vloženými, jsme nuceni je přetypovat na správný typ. Dokumentace k metodám vždy obsahuje informaci o tom, jaký typ se ve výsledném Vectoru nachází, takže je možné přetypovávat bezpečně.
Na obrázku je výřez z dokumentace k Notesovým objektům. V části Data type je vždy uveden typ prvků vložených do Vectoru:
Dokumentace je dostupná pomocí menu Help - Help Contents v části Lotus Domino Designer Basic User Guide and Reference > Java/CORBA Classes > Java Classes A-Z
Určení typu objektu ve Vectoru
Od Javy verze 5 je možné při inicializaci proměnné typu Vector určit typ objektu, jaký do něj zamýšlíme vložit. Později při načítání vložených objektů dostaneme přímo určený typ a můžeme se tak obejít bez přetypování.
Syntaxe vypadá následovně:
Vector<String> vector = new Vector<String>(); vector.add("Test1"); vector.add("Test2"); String prvni = vector.get(0); //přetypování není nutné
Výhodou je, že kompilátor v takovém případě i hlídá, že se do Vectoru nesnažíme vložit jiný typ, než který byl určen a na takovou chybu upozorní. Podobné syntaxe lze však využít pouze ve vlastnoručně psaném kódu, notesové Javové třídy této vlastnosti (nazvané Generics) nevyužívají, proto se přetypování nelze vyhnout.
Aby bylo možné psát kód podobný výše uvedenému v Domino Designeru 8 a vyšším, je nutné do notes.ini vložit řádek "JavaCompilerTarget=1.5" (bez uvozovek). Použití tohoto parametru může mít ještě další, někdy nežádoucí, efekty. Více na wiki stránkách.
Příklad
Příklad ilustruje přetypování proměnné uložené ve Vectoru na typ Agent. Vzorový kód představuje agenta, který prochází všechny agenty v databázi. U plánovaných agentů kontroluje, jestli se shoduje název serveru, na kterém má agent běžet, se serverem, na kterém skutečně databáze leží a vypíše informaci, pokud se servery liší (kód pro případnou změnu agenta je zakomentován).
K přetypování dochází po načtení objektu uloženého ve Vectoru, aby bylo možné s objektem pracovat jako s Agentem a využívat všech jeho metod.
import java.util.Iterator; import java.util.Vector; import lotus.domino.*; public class JavaAgent extends AgentBase { public void NotesMain() { try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); Database db = agentContext.getCurrentDatabase(); String currentServerName = db.getServer(); Vector agents = db.getAgents(); Iterator iterator = agents.iterator(); while (iterator.hasNext()) { Agent agent = (Agent) iterator.next(); //přetypování na Agent if (agent.getTrigger() == Agent.TRIGGER_SCHEDULED) { String serverName = agent.getServerName(); if (isOnDifferentServer(serverName, currentServerName)) { System.out.println("Agent " + agent.getName() + ": Nesouhlasí server agenta (nastaveno " + serverName + ")"); // agent.setServerName(currentServerName); // agent.save(); } } } } catch(Exception e) { e.printStackTrace(); } } private boolean isOnDifferentServer(String agentServerName, String dbServerName) { boolean result = false; if (agentServerName == null) { if (dbServerName.length() > 0) result = true; } else { if (!agentServerName.equals(dbServerName) == true) result = true; } return result; } }
Uvedený kód používá pro načtení všech položek ve Vectoru tzv. Iterátor - princip společný snad všem třídám typu Collections.
Další zdroje
Tvorba Javových agentů v Domino Designeru
Seznam komentářů (0)
| Přidat komentář |
