Úvod. Často jsme nuceni řešit problémy, které by reflexe řešila jasněji, stabilněji a přehledněji. Změny v požadavcích na programové vybavení

Podobné dokumenty
SW_06. Reflexe (reflection)

APNVZ_4 Adaptivní návrhové vzory. Microkernel Reflexe (reflection)

Reflexe. Aplikační programování v Javě (BI-APJ) - 8 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Úvod do programovacích jazyků (Java)

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

JAVA. Reflection API

typová konverze typová inference

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

Výčtový typ strana 67

Reflexe RTTI Runtime Type Identification

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Reflexe_03. Používání dynamického proxy

Generické programování

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

Algoritmizace a programování

Teoretické minimum z PJV

8 Třídy, objekty, metody, předávání argumentů metod

Z. Kotala, P. Toman: Java ( Obsah )

Soubor jako posloupnost bytů

KTE / ZPE Informační technologie

4. ZÁKLADNÍ POJMY Z OBJEKTOVĚ ORIENTOVANÉHO PROGRAMOVÁNÍ

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

9. přednáška - třídy, objekty

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

11 Diagram tříd, asociace, dědičnost, abstraktní třídy

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

PŘETĚŽOVÁNÍ OPERÁTORŮ

Paměť počítače. alg2 1

Seminář Java IV p.1/38

RMI Remote Method Invocation

Projekty pro výuku programování v jazyce Java

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Algoritmizace a programování

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

17. Projekt Trojúhelníky

Abstraktní datové typy: zásobník

Pokročilé programování na platformě Java. Úvod

Java Výjimky Java, zimní semestr

Dědičnost (inheritance)

Vytváření a použití knihoven tříd

Programování v Javě I. Leden 2008

1. Dědičnost a polymorfismus

Seminář Java II p.1/43

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

1. Programování proti rozhraní

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

Základy objektové orientace I. Únor 2010

Java - výjimky. private void vstup() throws IOException {... }

Typický prvek kolekce pro české řazení

UJO Framework. revoluční architektura beans. verze

Úvod do programování - Java. Cvičení č.4

Programování v Javě I. Únor 2009

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

8. přednáška: Soubory a proudy

20. Projekt Domácí mediotéka

Příklad : String txt1 = new String( Ahoj vsichni! ); //vytvoří instanci třídy String a přiřadí ji vnitřní hodnotu Ahoj vsichni!

Principy objektově orientovaného programování

Obsah. Úvod 11 Základy programování 11 Objektový přístup 11 Procvičování 11 Zvláštní odstavce 12 Zpětná vazba od čtenářů 12 Errata 13

OOPR_05. Případové studie

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Semin aˇr Java V yjimky Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Unor 2008 Radek Koˇc ı Semin aˇr Java V yjimky 1/ 25

PREPROCESOR POKRAČOVÁNÍ

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

1. Téma 12 - Textové soubory a výjimky

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Java Enum Java, zimní semestr ,2017 1

Abstraktní třída a rozhraní

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Objektově orientované programování

Úvod do programovacích jazyků (Java)

Úvod do programovacích jazyků (Java)

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Parametrizované třídy Generics generické třídy. JDK zavádí mimo jiné tzv. parametrizované třídy - generics

JAVA. Krátce o Reflection API

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

3. Třídy. Základní pojmy objektového programování. Třídy

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

Platformy NetBean a Eclipse. Úvod

7. Datové typy v Javě

5 Přehled operátorů, příkazy, přetypování

public static void main(string[] args) { System.out.println(new Main().getClass().getAnnotation(Greet.class).text());

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

boolean hasnext() Object next() void remove() Kolekce

Algoritmizace a programování

5 Rekurze a zásobník. Rekurzivní volání metody

10 Balíčky, grafické znázornění tříd, základy zapozdření

Více o konstruktorech a destruktorech

Objekty v PHP 5.x. This is an object-oriented system. If we change anything, the users object.

TÉMATICKÝ OKRUH Softwarové inženýrství

Viditelnost (práva přístupu) Tomáš Pitner, upravil Marek Šabo

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Komponenty v.net. Obsah přednášky

Java Cvičení 01. CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics

Programové konvence, dokumentace a ladění. Programování II 2. přednáška Alena Buchalcevová

Transkript:

Reflexe_01

Úvod Často jsme nuceni řešit problémy, které by reflexe řešila jasněji, stabilněji a přehledněji. Změny v požadavcích na programové vybavení mohou být uskutečněny pouze za podmínky přijetí rozhodnutí a modifikování kódu vycházejícího ze struktury programu.

Reflexe Jedná se o kroky: 1. Přezkoumat strukturu programu a dat 2. Přijmout rozhodnutí na základě přezkoumání. 3. Změnit chování, strukturu nebo data programu na základě přijatého rozhodnutí. Změny musí být provedeny osobou sedící za klávesnicí, místo samotným programem běžícím na počítači.

class HelloWorld { public void printname() { System.out.println( this.getclass().getname()); Objekt třídy vytiskne jméno třídy (včetně balíčků). (new HelloWorld()).printName() HelloWorld x = new HelloWorld(); x.printname(); Obsaženy všechny předchozí body. Metoda printname() prozkoumává objekt ohledně jeho třídy. Během toho je provedeno rozhodnutí, co tisknout. Bez zastínění, metoda je aplikovatelná na všechny podtřídy třídy HelloWorld. Metoda printname() je flexibilní, přizpůsobí se třídě, která ji zdědí.

Reflection úvod Reflexe (reflection) je schopnost pracovat se třídami (typy) a datovými atributy tříd jako s objekty. Reflection patří mezi adaptivní návrhové vzory. Poskytuje mechanismus pro změnu struktury chování softwarových systémů dynamicky. Podporuje modifikaci základních aspektů jako je typ struktury a mechanismus volání funkcí.

Reflection -úvod Tento vzor dělí aplikaci na dvě části: meta úroveňposkytuje informace o vybraných vlastnostech systému a umožňuje tak, aby si SW uvědomoval sám sebe. základní úroveň obsahující aplikační logiku. Aplikace je vytvořena na meta úrovni(nad meta úrovní). Změny informací v meta úrovniovlivňují následně chování základní úrovně.

Úroveň metamodelu, modelu, dat a procesů

Vztahy mezi modely a metamodely Čtyřvrstvá hierarchie OMG Vztahy vrstev vyjádřeny pomocí relace instance_of

Kontext, problém Kontext: Budování programových systémů, které apriori podporují svoji vlastní modifikaci. Problém: Programové systémy se vyvíjejí v čase, by měly být otevřené modifikacímna základě změny technologií a požadavků. Pro programové systémy je lepší specifikovat jejich architekturu otevřenou k modifikacím a rozšíření.

Problém Při řešení problému působí následující síly : Změna softwareje namáhavá (úmorná), náchylná k chybám a drahá. Softwarové systémy schopné adaptacemají obyčejně složitou vnitřní strukturu. Implementace služeb aplikace je rozšířena na mnoho malých komponent s odlišným vzájemným vztahem. Nevhodné techniky pro akceptování změn systému např. parametrizace, subclassing, copy paste.

Problém Změny SW mohou mít libovolný rozsah. Mohou být měněny i základní aspekty celého systému.

Řešení Vytvořit samouvědomující SW (self aware) a učinit některé aspekty této struktury a chování dosažitelnými pro adaptaci a změny. Vede to ke struktuře: meta úroveň a základní Vede to ke struktuře: meta úroveň a základní úroveň.

Meta úroveň Meta úroveň poskytuje self-representation programové aplikace a tím poskytuje vědomosti o její vlastní struktuře a chování. Meta objekty zapouzdřují a prezentují informace o programové aplikaci. instanceof «metaclass» java.lang.class instanceof meta level Pes class objects base level instanceof fido

Základní úroveň Základní úroveň definuje aplikační logiku. Implementace používá metaobjekty, aby udržela nezávislé ty aspekty, u kterých je pravděpodobnost změn. Např. komponenty základní úrovně mohou spolu vzájemně komunikovat prostřednictvím metaobjektu, které implementuje konkrétní uživatelsky definovaný mechanismu volání funkcí. Existuje specifikované rozhranípro manipulaci s metaobjekty.

Struktura Meta úroveň je složena s množiny metaobjektů. Každý metaobjektzapouzdřuje vybrané informace o jednotlivých aspektech struktury, chování, nebo stavu základní úrovně. Jsou tři zdroje těchto informací: 1. Informace jsou poskytovány za běhu prostředím systému. 2. Informace mohou být definovány uživatelem anotace. 3. Informace mohou být zjištěny ze základní úrovně za běhu programu aktuální stav výpočtu.

Struktura Všechny metaobjekty spolu poskytují vlastní reprezentaci (self-representation) aplikace. Metaobjektyvytvářejíinformace, které jsou jinak dostupné pouze implicitně. Takto jsou explicitně přístupné a modifikovatelné. Např. v distribuovaných systémech mohou existovat metaobjekty, které poskytují informace o fyzickém rozmístění komponentzákladní úrovně. Poskytují zjištění, zda komunikující partner je lokální nebo globální.

Reflekce v Javě balíček java.lang.reflect

import java.lang.reflect.*;.*; public class DumpMethods { public static void main(string args[]) { try { Class c = Class.forName(args args[0]); Method m[] = c.getdeclaredmethods(); for (int ( i = 0; i < m.length; i++) System.out.println(m[ (m[i]. ].tostring tostring()); catch (Throwable ( e) { System.err.println(e); Výpis metod třídy java.util.stack Spuštění s jedním argumentem: java DumpMethods java.util.stack c je classobject (objekt třídy) Spou pouštění: java DumpMethods java.util.stack public synchronized java.lang.object java.util.stack.pop() public java.lang.object java.util.stack.push(java.lang.object java.lang.object) public boolean java.util.stack.empty() public synchronized java.lang.object java.util.stack.peek() public synchronized int java.util.stack.search(java.lang.object java.lang.object) 18

Využití reflexe v Javě Nastavení používání reflexe Tři kroku vedoucí k využití balíčku java.lang.reflect. 1. Získat classobjekt java.lang.class, se kterým se bude manipulovat. java.lang.classse používá k reprezentaci tříd a rozhraní v běžícím javovskémprogramu. Jednou z možností získání objektu třídy je: Class c = Class.forName("java.lang.String"); získá se Class object pro řetězce Jiný způsob: Class c = int.class; // or Class c = Integer.TYPE;

Využití reflexe v Javě to vede k získání informací o základních typech. 2. Druhým krokem je zavolat metodu např. getdeclaredmethods(), k získání seznamu všech metod deklarovaných ve třídě.

Využití reflexe v Javě 3. Po té co jsou informace k dispozici, je třetím krokem využití API reflexe k manipulaci s informacemi. Např. sekvence příkazů: Class c = Class.forName("java.lang.String"); Method m[] = c.getdeclaredmethods(); System.out.println(m[0].toString()); Zobrazí textově první informaci uvedenou v řetězci.

Reflexe v hierarchii tříd Javy instanceof «metaclass» java.lang.class instanceof meta level Pes class objects base level instanceof fido Objekt fidoje instance od třídy Pes. Třída Pesje instance od třídy Class. Třída Classje instancí třídy Class. Třída Classje metatřída, protože její instance jsou třídy.

package prvni; class A { public class Instance1 { public static void main(string args[]) { try { Class cls = Class.forName( prvni.a"); boolean b1 = cls.isinstance(new Integer(37)); System.out.println(b1); boolean b2 = cls.isinstance(new prvni.a()); System.out.println(b2); catch (Throwable e) { System.err.println(e); Simulace operátoru instanceof() názvy balíčků se musí také uvádět Výpis: false true

import java.lang.reflect.*;.*; public class DumpMethods { public static void main(string args[]) { try { Class c = Class.forName(args args[0]); Method m[] = c.getdeclaredmethods(); for (int ( i = 0; i < m.length; i++) System.out.println(m[ (m[i]. ].tostring tostring()); catch (Throwable ( e) { System.err.println(e); Výpis metod třídy java.util.stack Spuštění s jedním argumentem: java DumpMethods java.util.stack c je classobject (objekt třídy) Spou pouštění: java DumpMethods java.util.stack public synchronized java.lang.object java.util.stack.pop() public java.lang.object java.util.stack.push(java.lang.object java.lang.object) public boolean java.util.stack.empty() public synchronized java.lang.object java.util.stack.peek() public synchronized int java.util.stack.search(java.lang.object java.lang.object)

import java.lang.reflect.*; public class Method1 { private int f1( Object p, int x) throws NullPointerException { if (p == null) throw new NullPointerException(); return x; Vyhledání metod dané třídy 1/2 public static void main(string args[]) { try { // Class cls = Class.forName( Method1"); Method1 method1 = new Method1(); Class cls = method1.getclass(); Method methlist[] = cls.getdeclaredmethods(); for (int i = 0; i < methlist.length; i++) { Method m = methlist[i]; System.out.println("name = " + m.getname()); System.out.println("decl class = " + m.getdeclaringclass()); Class pvec[] = m.getparametertypes(); for (int j = 0; j < pvec.length; j++) System.out.println(" param #" + j + " " + pvec[j]);

Class evec[] = m.getexceptiontypes(); for (int j = 0; j < evec.length; j++) System.out.println("exc #" + j + " " + evec[j]); System.out.println("return type = " + m.getreturntype()); System.out.println("-----"); catch (Throwable e) { System.err.println(e); Vyhledání metod dané třídy 2/2 name = f1 decl class = class Method1 param #0 class java.lang.object param #1 int exc #0 class java.lang.nullpointerexception return type = int ----- name = main decl class = class Method1 param #0 class [Ljava.lang.String; return type = void -----

import java.lang.reflect.*; public class Field1 { private double d; public static final int i = 37; String s = "testing"; Informace o datových atributech public static void main(string args[]) { try { // Class cls = Class.forName( Field1"); Field1 field1 = new Field1(); Class cls = field1.getclass(); Field fieldlist[] = cls.getdeclaredfields(); for (int i= 0; i < fieldlist.length; i++) { Field fld = fieldlist[i]; System.out.println("name = " + fld.getname()); System.out.println("decl class = " + fld.getdeclaringclass()); System.out.println("type = " + fld.gettype()); int mod = fld.getmodifiers();

System.out.println("modifiers = " + Modifier.toString(mod)); System.out.println("-----"); catch (Throwable e) { System.err.println(e); Informace o datových atributech name = d decl class = class Field1 type = double modifiers = private ----- name = i decl class = class field1 type = int modifiers = public static final ----- name = s decl class = class field1 type = class java.lang.string modifiers = -----

Význam reflexe Reflexeje schopnost běžícího programu zkoumat sám sebe, své programové okolí a měnit to co je závislé na výsledku zkoumání. K provádění sebezkoumání potřebuje mít program (knihovny) reprezentaci sama sebe. Těmto informacím se říká metadata. V OO světě jsou metadataorganizována v objektech nazývaných metaobjekty.

Význam reflexe Zkoumání sama sebe za běhu programu se nazývá introspekce (sebepozorování introspection). Existují tři možnosti, jak API reflexe může usnadnit změnu chování: 1. přímá modifikace metaobjektu 2. operace pro používání metadat(invokace dynamických metod)

Význam reflexe 3. intervenování (intercession) při němž je kódu dovoleno, aby intervenoval v různých fázích vykonávání programu. Java poskytuje bohatou řadu operací pro používání metadat, ale pouze několik důležitých schopností intervencí. Java se snaží vyhnout se komplikacím s přímou modifikací metaobjektů.

Význam reflexe Se znalostí reflexese modifikace kódu provádí daleko snadněji. Reflexe je mocná, ale není všespasitelná. Je třeba rozlišovat situace, kdy je reflexe absolutně nezbytná, od těch kdy její použití je výhodné, až po situace, kdy je třeba se jí vyhnout.

Příklad: implementace uživatelského rozhraní Java vizuální komponenty: vlastní, open source, třetí strana všechny komponenty integrované do uživatelského rozhraní. Každá komponenta poskytuje setcolor() má parametr java.awt.color. Jediná společná třída java.lang.object není společná třída na deklaraci setcolor().

Alternativy řešení Refaktorovatkomponenty pro implementaci společného rozhraní, deklarující setcolor(). neřeší standardní javovskékomponenty a komponenty třetí strany, open source nemusí změny akceptovat není podpora. Implementace adapteru pro každou komponentu. každý takový adapter musí implementovat společné rozhraní a delegovat volání setcolor() na komponentu.

Alternativy řešení velké množství tříd komponent způsobí velký počet tříd k údržbě, velký počet instancí za běhu programu. Použití metody instanceof() a přetypování za běhu programu nechává několik problémů údržby na dodavatelské firmě. způsobí nafouknutí kódu z důvodu podmínek a přetypování, kód se stane dvojicí s každým konkrétním typem

Alternativy řešení Každá z alternativ zahrnuje změny programu, které upraví nebo zjistí typ komponenty. V podstatě je třeba nalézt metodu setcolor() a vyvolat ji. Programování s využitím reflexe:

public static void setobjectcolor( Object obj, Color color ) { Class cls = obj.getclass(); //#1 try { Method method = cls.getmethod( "setcolor", //#2 new Class[] {Color.class ); method.invoke( obj, new Object[] {color ); //#3 catch (NoSuchMethodException ex) { //#4 throw new IllegalArgumentException( cls.getname() + " does not support" + "method setcolor(:color)"); catch (IllegalAccessException ex) { //#5 throw new IllegalArgumentException( "Insufficient access permissions to call" + "setcolor(:color) in class " + cls.getname()); catch (InvocationTargetException ex) { //#6 throw new RuntimeException(ex); #1 dotaz objektu na třídu #2 dotaz na setcolor(), která má argument Color (1,2 formy introspekce sebepoznání) #3vyvolání metody setcolor() erflektivní metoda dynamická invokace #4třída objektu neposporuje netodu setcolor() #5třída nemá privilegia přístupu vyvolat protected, packagenebo privatemodifikátor metody setcolor() #6vyvolaná metoda setcolor() vyhazuje výjimku

Alternativy řešení Dynamická invokace dovoluje vyvolat metodu objektu při jeho běhu. V příkladu se neví, kterou metodu setcolor() vyvolat. Předá se pouze objekt a parametr. Pro dynamickou invokaci je důležité mít dobře ošetřené chybové stavy. Každé zpracování za běhu programu mírně zvyšuje nároky na čas výpočtu, ale nijak podstatně.

Zkoumání běžících programů Reflexe je schopnost programu zkoumat a měnit svoje chování a strukturu za běhu programu. Přemýšlejme o introspekci (sebepoznání) jako pohledu do zrcadla na sebe sama. Zrcadlo poskytuje vaši reprezentaci ke zkoumání. Toto zkoumání dodává řadu užitečných informací.

Zkoumání běžících programů Např. jak jde barva košile k vašim kalhotám, nebo že máte něco zeleného na tváři to může změnit vaši garderobu a hygienu. Zrcadlo vám také řekne něco o vašem chování úsměv, přehánění gest.. To pak může vést ke změnámve vašem chování.

Introspekce programu (sebepozorování) K introspekci programu potřebujeme přístup k reprezentaci programu. Tato vlastní representace (selfrepresentation) je nejdůležitějším strukturálním prvkem systému reflexe. Zkoumáním vlastní reprezentace může program získat pravé informace o struktuřea chování k provedení důležitých rozhodnutí.

Introspekce programu (sebepozorování) V předchozím příkladu instance Class a Method jsou využity k nalezení vyvolání vhodné metody setcolor(). Tyto instance (objekty) jsou částí javovské vlastní reprezentace. Objekty, které jsou částí vlastní reprezentace se odkazujeme jako na metaobjekty.

Metadata Metadatajsou data o datech. Katalogizační lístek v knihovně obsahuje data o dané knize. Metadatadatabáze struktura databáze, názvy sloupců. Na webu by metadata zrychlila vyhledávání.

Introspekce programu (sebepozorování) Metaje předpona, znamenající za. Metaobjektyjsou objekty, které udržují informace o programu. Classa Methodjsou třídy, jejichž instance představují program. Odkazuje se na ně jako na třídy metaobjektů. Třídy metaobjektůtvoří většinu toho, co tvoří API reflexe Javy.

Introspekce programu (sebepozorování) Objekty, které jsou používány k doprovázení hlavní aplikace se nazývají objekty základní úrovně (base-level object).

Dog class object metalevel instanceof base level fido base/level object Dog je objekt třídy (classobject), metaobjekt, který představuje třídu Dog. Objekt fidoje instance třídy Dog. Relace instanceofspojuje objekt base levels objektem na úrovni metalevel.

Nalezení metody za běhu programu Class cls = obj.getclass(); metoda getclass() zabezpečí přístup k objektu třídy (objectclass) za běhu a vrací instanci třídy java.lang.class. Instance třídy Classjsou metaobjekty, které Java používá k reprezentaci tříd, které tvoří program. classobjekt objekt třídy je instancí od třídy java.lang.class.

Nalezení metody za běhu programu Classobjekty poskytují programování metadatjako datových atributů, metod, konstruktorů a vnořených tříd. Classobjekty také poskytují informace o Classobjekty také poskytují informace o hierarchii dědičnosti a poskytují přístup k reflektivním prostředkům.

Vyvolání metody Method method = cls.getmethod ( setcolor, new Class[] {Color.class); První parametr - řetězec požadované metody. Druhý parametr pole classobjects(objektů tříd) které identifikují parametry metod. Konkrétně jeden parametr typu Color. Jakýkoli název třídy následovaná.classse vyhodnotí jako objekt třídy (class object).

Metody třídy Classpro dotazy Metoda MethodgetMethod(String name, Class[] parametertypes) Method[] getmethods() Method getdeclaredmethod( Stringname, Class[] parametertypes) Popis Vrací objekt Method (deklarovaný nebo zděděný), kterýpředstavuje cílový Classobjekt (objekt třídy) spolu se signaturou druhého parametru. Vrací pole objektů třídy Methodjak deklarovaných, tak zděděných. Vrací objekt typu Method, který představuje deklarovanou metodu a signaturu specifikovanou ve druhém parametru. Method[] getdeclaredmethods() Vrací pole objektůtřídy Method, které představují všechny metody deklarované v cílové třídě Class objektu.

Reprezentace typů pomocí class objects objektů třídy Class null představuje pole nulové délky. Reflexe Javy používá instance třídy Classk reprezentaci typů. Java reprezentuje primitivní typy, pole a rozhraní také pomocí classobjects(objektů tříd). Omezení: není možné vytvářet nové instance od primitivních typů a rozhraní.

Metody třídy Classpro práci s reprezentaci typů ClassgetName() Metoda ClassgetComponentType() Popis Vrací plně kvalifikované jméno cílového objektu třídy. Je-li cílovýobjekt classobjectpro pole, vrací objekt Class reprezentující typ komponenty. boolean isarray() boolean isinterface() Vrací true, je-li cílový class object polem. Vrací true, je-li cílový class object rozhraním. booleanisprimitive() Vrací true, je-li cílový classobjectprimitivním typem nebo void.

Reprezentace primitivních typů Classobjekty (objekty tříd) reprezentují všech 8 primitivních typů. Methodm= Vector.class.getMethod( get, new Class[] {int.class); Klíčovéslovovoidnení v Javě typem (použití v metodách nic nevracející). Java má ale class objekt pro reprezentaci void. Metoda isprimitive() vrací truepro void.class.

Reprezentace rozhraní Java má classobjekt pro reprezentaci každého deklarovaného rozhraní. Tyto classobjekty mohou být využity pro indikaci parametrů pro typ rozhraní. Metoda addall() bere implementaci rozhraní Collection jako argument. Methodm = Vector.class.getMethod( addall, new Class[] {Collection.class);

Reprezentacetypupolí V Javě jsou objekty polí, ale jejich třídy jsou vytvořeny JVM za běhu programu. Javovskétřídy arrayimplementují rozhraní Cloneable a java.io.serializable. Ke specifikaci jednorozměrného pole objektů použijeme: Object[].class. Method m = Vector.class.getMethod( copyinfo, new Class[] {Object[].class);

java.lang.reflect.method Metoda Popis ClassgetDeclaredClass() Class[] getexceptiontypes() Vrací Classobjekt, který deklaruje metodu reprezentovanou tímto objektem Method. Vrací pole Classobjektů, které představují typy výjimek, deklarované v objektu Method. intgetmodifiers() String getname() Class[] getparametertype() Vrací modifikátorymetody zakódované do typu int. Vrací jméno metody představované tímto Methodobjektem. Vrací pole Classobjektů reprezentující formální parametry v deklarované pořadí. Class getreturntype() VracíClassobjekt reprezentující typ vracený metodou reprezentovanou objektem Method. Object invoke(object obj, Object[] args) Vyvolává metodu reprezentovanou objektem Method s polem parametrů.

Použití dynamického vyvolávání (dynamicinvocation) Dynamická invokace dovoluje programu vyvolat metodu, objektu za běhu programu bez specifikace této metody v době kompilace. Nevíme kterou metodu setcolor() vyvolat během zápisu programu. method.invoke(obj, new Object[] {color); Proměnná colorobsahuje proměnnou typu Color.

Dynamické vyvolávání Je-li metoda setcolor()deklarovaná jako třídní (static), pak objse nebere do úvahy, může být null.

Primitivní typy a dynamická invokace Druhý parametr invokace je Object array. Je-li typ parametru primitivní, metoda invoke() předpokládá odpovídající pole args prvků, bude zabaleno do obalujícího objektu, který obsahuje argument. intparametr bude zabalen do java.lang.integera předán do pole args.

Primitivní typy a dynamická invokace Primitivní typy musí být převedeny na obalové typy a převedeny na primitivní typy když jsou vráceny. Method m = obj.getclass().getmethod( hashcode, null); ProzkoumánímetodyhashCode(), která nemá parametry.

Primitivní typy a dynamická invokace int code = ((Integer) method.invoke(obj, null)); Zaznamenání hash kódu dané metody.

Problémy invokace a jejich řešení Metoda musí být invokovaná na objekt, jehož instance byla deklarovaná ve třídě, jinak výjimka IlllegalArgumentException. Metodu setcolor() nelze cashovat. Každá metoda je v Javě identifikovaná jak její signaturou, tak deklarovanou třídou.

Grafické znázornění Java rozlišuje metody setcolor() jako dvě různé. Metoda setcolor() je stejná pro Animal a pro Dog. Metoda setcolor() je různá pro Animal a Shape.

Problémy invokace a jejich řešení Pokud třída vyvolávající metodu invoke() nemá odpovídající privilegia pro metodu, je vyhozena výjimka IllegalArgumentException, např. metoda private je volána vně dané třídy. Výjimku IllegalArgumentException může vyvolat: daná třída nemá uvedenou metodu, pole args má nesprávnou velikost

Problémy invokace a jejich řešení je-li nějaká výjimka vyvolaná invokovanou metodou, je výjimka zabalena do InvocationTargetExceptiona potom vyhozena.

dolly je klonovaná ovce. Objekt dolly je instance třídy Sheep. Třída Sheepje podtřídou Mammela implementuje rozhraní Cloneable.

Navigace hierarchií dědičnosti Reflektivnímetodaje zděděná a má modifikátor protected, takže není dostupná. Method m = cls.getmethod( setcolor, new Class[] {Color.class); Napsat metodu, která prochází také hiearchií dědičnosti.

public static Method getsupportedmethod( Class cls, String name, Class[] paramtypes) throws NoSuchMethodException { if (cls == null) { throw new NoSuchMethodException(); try { return cls.getdeclaredmethod( name, paramtypes ); catch (NoSuchMethodException ex) { return getsupportedmethod( cls.getsuperclass(), name, paramtypes ); Metoda getsupported() je rekurzivní metoda, která traverzuje hierarchii dědičnosti a hledá metodu s odpovídající signaturou. Metoda vrací Class objekt, který představuje zděděnou třídu. Pokud neexistuje taková třída, vrací se třída Object, na kterou metoda getsupportedmethod() vrací null.

public static void setobjectcolor( Object obj, Color color ) { Class cls = obj.getclass(); try { Method method = Mopex.getSupportedMethod( cls, "setcolor", new Class[] {Color.class ); method.invoke( obj, new Object[] {color ); catch (NoSuchMethodException ex) { throw new IllegalArgumentException(cls.getName() + " does not support" + "method setcolor(:color)"); catch (IllegalAccessException ex) { throw new IllegalArgumentException( "Insufficient access permissions to call" + "setcolor(:color) in class " + cls.getname()); catch (InvocationTargetException ex) { throw new RuntimeException(ex); Tento kód dovoluje metodě setcolor() zpřístupnit metaobjekty s modofikátoryprivate, packagea protected, které nezpřístupní metoda getmethod(). Toto řešení ale negarantuje přístup k invokované metodě. Pokud nemá metoda setobjectcolor() přístup k zděděné metodě, kde to chceme používat, vyhodí se výjmka IllegalAccessException.

Metody pro introspekci hierarchie (sebepozorování) Metoda Class[]getInterface() ClassgetSuperClass() booleanisassignablefrom(classcls) booleanisinstance(object obj) Popis Vrací pole Class objektů, které představují přímé nadrozhranídaného Class objektu. Vrací Classobjekt, který představuje přímou nadtřídu daného Classobjektu, nebo nullje-li Classobjekt třída Objectnebo void. Vrací true, je-li třída nebo rozhraní reprezentované cílovým Classobjektem je buď stejné nebo nadtřída nebo nadrozhraníspecifikovaného parametru Class. Vrací true, je-li specifikovaný Objectje přiřazením kompatibilní s objektovou reprezentací cílového objektu Class.

x.isassignablefrom(y) Object.class.isAssignableFrom(String.class); double.class.isassignablefrom(double.class); vyhodnocení true Object.class.isAssignableFrom(double.class); vyhodnocení false

Překvapení Metoda isinstance() má zajímavé použití: Class.class.isInstance(Class.class) true To znamená, že classobjekt pro Classje instance sama sebe, což vede ke kruhové závislosti. Classje příkladem metatřídy, která se používá k označení tříd, jejichž instance jsou třídy.

Reflexev hierarchiitříd Javy Objekt fidoje instance od třídy Pes. Třída Pesje instance od třídy Class. Třída Classje instancí třídy Class. Třída Classje metatřída, protože její instance jsou třídy.

Reflexe v hierarchii tříd Javy Třída Object nejvyšší třída v hierarchii, metaclasses jsou podtřídami třídy Object. 1. To znamená, že metody třídy Object jsou součástí API reflexe.

Reflexe v hierarchii tříd Javy 2. Všechny javovské třídy jsou instancemi od jedné metatřídy Class. Tyto dvě podmínky vytvářejí cyklus v diagramu. Class.class.isInstance(Object.class); true Object.class.isAssignableFrom(Class.class); true

Reflexe v hierarchii tříd Javy V Javě má každý objekt jednu třídu, která vytváří instance a všechny třídy jsou podtřídami třídy Object. Třída Object je částí API reflexe. Všechny metatřídy jsou podtřídami třídy Object. Každá z metod reflexe může být používaná v reflektivním programování.

Shrnutí Reflexe dovoluje programu prozkoumat sám sebe a dělat změny do své struktury a chování za běhu programu. Metaobjektytříd Classa Methodreprezentují třídy a metody běžícího programu. Jiné metaobjektyreprezentují jiné části programu jako např. datové atributy, zásobníky volání a loader.

Shrnutí Classmá další metody, které podporují tyto jiné metaobjekty. Zjišťování informací z těchto metaobjektůse nazývá introspekce (pozorování sebe sama). Metaobjektytako dovolují dynamickou invokaci metod. Řešení s využitím reflexe začíná zjišťováním informací o běžícím programu z metaobjektů.

Shrnutí Po zjištění těchto informací, reflektivní program použije tyto informace na dělání změn v běžícím programu.

Volání metodypodle jména Program chce vyvolat metodu add(),ale neví to, až do doby běhu programu. To znamená, že jméno metody je určeno až za běhu programu viz, následující program. metoda getmethod()se používá k nalezení metody ve třídě, která má dva integerparametrya odpovídající jméno. po jejím nalezení je přiřazena do objektu Method k vyvolání metody se musí vytvořit seznam parametrů s odpovídajícími integer hodnotami.

import java.lang.reflect.*; public class Method2 { public int add(int a, int b) { return a + b; public static void main(string args[]) { try { Method2 method2 = new Method2(); Class cls = method2.getclass(); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; // deklarace partypes[1] = Integer.TYPE; Method meth = cls.getmethod( "add", partypes); // dana metoda s uvedenymi parametry Method2 methobj = new Method2(); Object arglist[] = new Object[2]; // počet argumentů arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = meth.invoke(methobj, arglist); Integer retval = (Integer)retobj; System.out.println(retval.intValue()); catch (Throwable e) { System.err.println(e); Vyvolání (exekuce) metody podle jména Výpis vrací součet zadaných parametrů: 84

import java.lang.reflect.*; public class Constructor2 { public Constructor2() { Vytváření nových objektů 1/2 public Constructor2(int a, int b) { System.out.println( "a = " + a + " b = " + b); public static void main(string args[]) { try { Class cls = Class.forName( Constructor2"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Constructor ct = cls.getconstructor(partypes);

Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = ct.newinstance(arglist); catch (Throwable e) { System.err.println(e); Vytváření nových objektů 2/2 Výpis a = 37 b = 47