SW_06. Reflexe (reflection)

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

Ú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í

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

Úvod do programovacích jazyků (Java)

RMI Remote Method Invocation

KTE / ZPE Informační technologie

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

Algoritmizace a programování

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

Java Výjimky Java, zimní semestr

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

Generické programování

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

Soubor jako posloupnost bytů

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

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

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

Distribuované systémy a výpočty

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/

typová konverze typová inference

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

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

Typický prvek kolekce pro české řazení

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

Příklad aplikace Klient/Server s Boss/Worker modelem (informativní)

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

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

JAVA. Reflection API

Reflexe RTTI Runtime Type Identification

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

Teoretické minimum z PJV

17. Projekt Trojúhelníky

1. Programování proti rozhraní

Abstraktní datové typy: zásobník

Vláknové programování část V

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

Vlákno odlehčený proces kód vlákna, zásobník privátní ostatní sdíleno s dalšími vlákny téhož procesu

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

Programování v Javě I. Leden 2008

Algoritmizace a programování

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

Seminář Java II p.1/43

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

Úvod do programovacích jazyků (Java)

Seminář Java IV p.1/38

Výjimky. Tomáš Pitner, upravil Marek Šabo

Java a XML. 10/26/09 1/7 Java a XML

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

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

OOPR_05. Případové studie

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

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

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

Java Enum Java, zimní semestr ,2017 1

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

Java Řetězce Java, zimní semestr

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

20. Projekt Domácí mediotéka

Reflexe_02. Přístup k datovým atributům třídy pomocí reflexe

Vlákna. První jednoduchý program s vlákny:

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

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

Výčtový typ strana 67

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

Dědičnost (inheritance)

UJO Framework. revoluční architektura beans. verze

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

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

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

7. Datové typy v Javě

7 Jazyk UML (Unified Modeling Language)

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

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

Regulární výrazy. Vzory

Třídy, polymorfismus. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

public class Karel { private int position; public boolean issmiling; public int getposition() { return position;

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

Datové struktury obsah přednášky 1. Úvod 2. Třídy Type-wrapper (obalový typ) pro primitivní typy automatické převody 3. Automatické převody mezi

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

Java a Caché IV: Manipulace s objekty

Distribuované systémy a výpočty

VIII. Seminář Java VIII p.1/36

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

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

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.

Java - řazení objektů

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

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

Principy objektově orientovaného programování

Výjimky. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

Podmínky na zápočet. Java, zimní semestr

7 Jazyk UML (Unified Modeling Language)

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.

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

Práce s textem. Třída Character. Třída Character. Třída Character. reprezentuje objekty zapouzdřující hodnotu typu char (boxing / unboxing)

O autorovi O odborném korektorovi Úvod 17 Vývoj jazyka Java Java SE 8 Struktura této knihy Předchozí zkušenosti s programováním nejsou potřebné

Jazyk C# (seminář 6)

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 )/ ;

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

Vlákna. První jednoduchý program s vlákny:

Transkript:

SW_06 Reflexe (reflection) 1

Ú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. 2 2

Jedná se o kroky: Reflexe 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. 3 3

class HelloWorld { public void printname() { System.out.println( this.getclass().getname()); (new HelloWorld()).printName() HelloWorld x = new HelloWorld(); x.printname(); Poznámky Objekt třídy vytiskne jméno třídy (včetně balíčků). 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í. 5 5

Souvislost s ostatními vzory Reflexe: poskytuje dvou úrovňovou architekturu. základní úroveň (base level) koresponduje s kombinací microkernelu a interních serverů meta úroveň koresponduje s činností externích serverů, protože ty umožňují dynamicky měnit funkcionalitu, podobně jako metaúroveň vzoru ferlexe. 6

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í. 7

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 úrovni ovlivňují následně chování základní úrovně. 8

Úroveň metamodelu, modelu, dat a procesů 9

Vztahy mezi modely a metamodely M3 Metametamodel MOF instance of instance of M2 Metamodel M1 Model Čtyřvrstvá hierarchie OMG Vztahy vrstev vyjádřeny pomocí relace instance_of instance of M0 Data 10

Kontext: Kontext, problém 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ím na 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í. 11

Problém Při řešení problému působí následující síly : Změna software je namáhavá (úmorná), náchylná k chybám a drahá. Softwarové systémy schopné adaptace mají 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. 12

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

Ř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í úroveň. 14

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 ba se level instanceof fido 15

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. 16

Struktura Meta úroveň je složena s množiny metaobjektů. Každý metaobjekt zapouzdř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. 17

Struktura Všechny metaobjekty spolu poskytují vlastní reprezentaci (self-representation) aplikace. Meta objekty vytvář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í komponent základní úrovně. Poskytují zjištění, zda komunikující partner je lokální nebo globální. 18

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

import java.lang.reflect.*; public class DumpMethods { public static void main(string args[]) { try { Class c = Class.forName(args[0]); Method m[] = c.getdeclaredmethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].toString()); catch (Throwable e) { System.err.println(e); Poznámky 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) 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) 20

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 class objekt java.lang.class, se kterým se bude manipulovat. java.lang.class se používá k reprezentaci tříd a rozhraní v běžícím javovském programu. 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; 21

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ě. 22

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. 23

Reflexe v hierarchii tříd Javy Objekt fido je instance od třídy Pes. Třída Pes je instance od třídy Class. Třída Class je instancí třídy Class. Třída Class je metatřída, protože její instance jsou třídy. 24

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. 25

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); Object.class.isAssignableFrom(Class.class); 26

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í. 27

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); Poznámky Simulace operátoru instanceof() názvy balíčků se musí také uvádět Výpis: false true 28

import java.lang.reflect.*; public class Method1 { private int f1( Object p, int x) throws NullPointerException { if (p == null) throw new NullPointerException(); return x; Poznámky 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]); 29

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); Poznámky 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 ----- 30

import java.lang.reflect.*; public class Field1 { private double d; public static final int i = 37; String s = "testing"; Poznámky 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(); 31

System.out.println("modifiers = " + Modifier.toString(mod)); System.out.println("-----"); catch (Throwable e) { System.err.println(e); Poznámky 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 = ----- 32

Volání (exekuce) metody podle 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 integer parametry a 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. 33

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); Poznámky Vyvolání (exekuce) metody podle jména Výpis vrací součet zadaných parametrů: 84 34

import java.lang.reflect.*; public class Constructor2 { public Constructor2() { Poznámky 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); 35

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); Poznámky Vytváření nových objektů 2/2 Výpis a = 37 b = 47 36

import java.awt.point; import java.lang.reflect.constructor; public class ShowReflection { Poznámky Využití konstruktorů public static void main(string args[]) { Constructor[] cc = Point.class.getConstructors(); Constructor cons = null; for (int i = 0; i < cc.length; i++){ // kontrolní výpis System.out.println(cc[i].toString()); // celkový výpis if (cc[i].getparametertypes().length == 2) cons = cc[i]; vybere konstruktor se dvěma parametry try { Object obj = cons.newinstance( new Object[] { new Integer(3), new Integer(4) ); System.out.println(obj); catch (Exception e) { System.out.println("Exception: " + e.getmessage()); 37

Poznámky Výpisy public java.awt.point(java.awt.point) public java.awt.point(int,int) public java.awt.point() java.awt.point[x=3,y=4] Třída Point má tři konstruktory 38

import java.lang.reflect.*; public class Field2 { public double d; public static void main(string args[]) { try { Class cls = Class.forName( Field2"); Field fld = cls.getfield("d"); Field2 f2obj = new Field2(); System.out.println("d = " + f2obj.d); fld.setdouble(f2obj, 12.34); System.out.println("d = " + f2obj.d); catch (Throwable e) { System.err.println(e); Poznámky Změna hodnot datových atributů 39

Balíčky v Javě java.lang.class a java.lang.reflect poskytují programové konstrukce pro získání běhových (run-time) reflektivních informací o třídách a objektech informace typu: nadtřída a její datové typy rozhraní nadtřídy 40

Testování serializovatelnosti Testing for Serializability příklad testuje, zda třída objektu, nebo libovolná nadtřída implementovala rozhraní Serializable pomocná třída má pouze statickou metodu isserializable() SerializableTester.isSerializable( java.util.calendar.getinstance()); SerializableTester.isSerializable( new Object()); 41

import java.io.serializable; public class SerializableTester { private static final String serial = "java.io.serializable"; public static boolean isserializable( Object obj ) { if ( obj == null ) return false; Class c = obj.getclass(); do { Class[ ] ifaces = c.getinterfaces(); for ( int i = 0; i < ifaces.length; i++ ) if ( serial.equals( ifaces[ i ].getname() ) ) return true; c = c.getsuperclass(); while ( c!= null ); // cykluj, dokud trida je Object return false; Poznámky Metoda getclass() deklarovaná ve třídě Object metoda getinterface() vrací pole rozhraní metoda getsuperclass() vrací nadtřídu 42

public class SerializableTest { public static void main(string[] args) { boolean q = SerializableTester.isSerializable( java.util.calendar.getinstance()); if(q) System.out.println("Calendar je serializovatelny"); else System.out.println("Calendar neni serializovatelny"); Poznámky q = SerializableTester.isSerializable(new Object()); if(q) System.out.println("Object je serializovatelny"); else System.out.println("Object neni serializovatelny"); Výpis Calendar je serializovatelný Object není serializovatelný 43

Získání běhových informací (run-time) Předpoklad: aplikace nahraje třídu a potřebuje získat informace o třídě java.lang.reflect obsahuje třídy jako: Constructor, Field, Modifier třída ClassInfo očekává jména tříd jako argumenty příkazů DiningPhilosophers Philosopher Philosopher je další třída 44

Získání běhových informací Class c = Class.forName(s); Program určí modifikátory třídy (public ), určí, zda se jedná o třídu nebo rozhraní. Program vyvolá metody getdeclaredconstructors() a getdeclaredmethods() a dostane seznamy konstruktorů a metod deklarovaných ve třídě, spolu s jejich atributy, typy argumentů a výjimkami, které mohou být vyhozeny. Program vypíše seznam atributů dané třídy. 45

import java.lang.reflect.*; public class ClassInfo { private static String indent = " "; public static void main( String[ ] args ) throws ClassNotFoundException { if ( args.length < 1 ) return; // exit if no classes given for ( int i = 0; i < args.length; i++ ) { new ClassInfo().printInfo( args[ i ] ); System.out.println(); private void printinfo( String s ) throws ClassNotFoundException { Class c = Class.forName( s ); String modifiers = stringifymodifiers( c.getmodifiers() ); String name = c.getname(); if ( c.isinterface() ) System.out.print( modifiers + name ); else System.out.print( modifiers + " class " + name + " extends " + c.getsuperclass().getname() ); Class[ ] interfaces = c.getinterfaces(); if ( interfaces!= null && interfaces.length > 0 ) { if ( c.isinterface() ) System.out.print( " extends " ); else System.out.print( " implements " ); for ( int i = 0; i < interfaces.length; i++ ) { if ( i > 0 ) System.out.print( ", " ); System.out.print( interfaces[ i ].getname() ); Poznámky Parametr třída DiningPhils 46

System.out.println( " {" ); System.out.println( indent + "// Constructors" ); Constructor[ ] constructors = c.getdeclaredconstructors(); for ( int i = 0; i < constructors.length; i++ ) printmethod( constructors[ i ] ); System.out.println( indent + "// Other methods " ); Method[ ] methods = c.getdeclaredmethods(); for ( int i = 0; i < methods.length; i++ ) printmethod( methods[ i ] ); System.out.println( indent + "// Fields " ); Field[ ] fields = c.getdeclaredfields(); if ( fields!= null ) for ( int i = 0; i < fields.length; i++ ) printfield( fields[ i ] ); System.out.println( "" ); //end of printinfo method Poznámky private void printmethod( Member m ) { Class rt = null; Class[ ] params, exceptions; if ( m instanceof Method ) { // nonconstructor method Method method = (Method) m; rt = method.getreturntype(); params = method.getparametertypes(); exceptions = method.getexceptiontypes(); 47

else { // a constructor Constructor c = (Constructor) m; params = c.getparametertypes(); exceptions = c.getexceptiontypes(); System.out.print( indent + stringifymodifiers( m.getmodifiers() ) + " " + (( rt!= null )? gettypename( rt ) + " " : "" ) + m.getname() + "( " ); for ( int i = 0; i < params.length; i++ ) { if ( i > 0 ) System.out.print( ", " ); System.out.print( gettypename( params[ i ] ) ); if ( params.length > 0 ) System.out.print( " )" ); // at least 1 param else System.out.print( ")" ); // no params if ( exceptions.length > 0 ) System.out.print( " throws" ); for ( int i = 0; i < exceptions.length; i++ ) { if ( i > 0 ) System.out.print( ", " ); System.out.print( gettypename( exceptions[ i ] ) ); System.out.println( ";" ); Poznámky 48

//*** printmethod private void printfield( Field f ) { System.out.println( indent + stringifymodifiers( f.getmodifiers() ) + " " + gettypename( f.gettype() ) + " " + f.getname() + ";" ); Poznámky private String stringifymodifiers( int i ) { return (i == 0)? "" : Modifier.toString( i ); private String gettypename( Class c ) { String b = ""; while( c.isarray() ) { b += "[ ]"; c = c.getcomponenttype(); return c.getname() + b; 49

reflection.diningphils public class reflection.diningphils extends java.lang.object { // Constructors public reflection.diningphils( ); // Other methods public static void main( java.lang.string[ ] ); private void init( int ); public int getcount( ); public boolean getchopstick( int ); public void setchopstick( int, boolean ); private void initphils( ); public void dumpstatus( ); public int generatetimeslice( ); private boolean moretostart( ); // Fields private int n; private reflection.philosopher[ ] phils; private boolean[ ] chops; private java.util.random r; private static final int maxphils; private static final int maxeat; private static final int mineat; Výpisy Poznámky 50

reflection.philosopher class reflection.philosopher extends java.lang.thread { // Constructors public reflection.philosopher( reflection.diningphils, int ); // Other methods public void run( ); public void settimeslice( int ); public boolean geteat( ); public boolean chopsticksfree( ); public void setleftchopstick( boolean ); public void setrightchopstick( boolean ); private void releasechopsticks( ); private synchronized void grabchopsticks( ); private void eat( ); private void think( ); private void takechopsticks( ); private void seteat( boolean ); private void pause( ); // Fields private reflection.diningphils host; private boolean iseating; private int index; private int ts; Výpisy Poznámky 51

package reflection; import java.util.random; public class DiningPhils { private int n; private Philosopher[ ] phils; private boolean[ ] chops; private Random r; private static final int maxphils = 24; private static final int maxeat = 4; // seconds private static final int mineat = 1; // seconds Výpisy Poznámky Třída DiningPhils public int getcount() { return n; public boolean getchopstick( int i ) { return chops[ i ]; public void setchopstick( int i, boolean v ) { chops[ i ] = v; private void init( final int N ) { r = new Random(); n = (N < 0 N > maxphils)? maxphils : N; chops = new boolean[ n ]; phils = new Philosopher[ n ]; initphils(); dumpstatus(); 52

//*** Create phil threads and start them in random order. private void initphils() { for ( int i = 0; i < n; i++ ) { phils[ i ] = new Philosopher( this, i ); phils[ i ].settimeslice( generatetimeslice() ); phils[ i ].setpriority( Thread.NORM_PRIORITY - 1 ); while ( moretostart() ) { int i = Math.abs( r.nextint() ) % n; if (!phils[ i ].isalive() ) { System.out.println( "### Philosopher " + String.valueOf( i ) + " started." ); phils[ i ].start(); System.out.println( "\nphilosophers Chopsticks" + "\n(1 = eating 0 = thinking) (1 = taken 0 = free)" ); private boolean moretostart() { for ( int i = 0; i < phils.length; i++ ) if (!phils[ i ].isalive() ) return true; return false; Výpisy Poznámky Třída DiningPhils 53

public int generatetimeslice() { int ts = Math.abs( r.nextint() ) % (maxeat + 1); if ( ts == 0 ) ts = mineat; return ts; public void dumpstatus() { for ( int i = 0; i < n; i++ ) System.out.print( (phils[ i ].geteat())? 1 : 0 ); for ( int i = n; i < maxphils + 4; i++ ) System.out.print( " " ); for ( int i = 0; i < n; i++ ) System.out.print( (chops[ i ])? 1 : 0 ); System.out.println(); Výpisy Poznámky Třída DiningPhils public static void main( String[ ] args ) { if ( args.length < 1 ) { System.err.println( "DiningPhils <# of philosophers>" ); System.exit( -1 ); DiningPhils self = new DiningPhils(); self.init( Integer.parseInt( args[ 0 ] ) ); 54

class Philosopher extends Thread { private DiningPhils host; private boolean iseating; private int index; private int ts; public Philosopher( DiningPhils HOST, int i ) { host = HOST; index = i; public void settimeslice( int TS ) { ts = TS; public boolean chopsticksfree() { return!host.getchopstick( index ) &&!host.getchopstick( (index + 1) % host.getcount() ); public void setleftchopstick( boolean flag ) { host.setchopstick( index, flag ); public void setrightchopstick( boolean flag ) { host.setchopstick( (index + 1) % host.getcount(), flag ); private void releasechopsticks() { host.setchopstick( index, false ); host.setchopstick( (index + 1) % host.getcount(), false ); Výpisy Poznámky Třída Philosopher 55

public void run() { while ( true ) { grabchopsticks(); eat(); think(); private synchronized void grabchopsticks() { while (!chopsticksfree() ) try { wait(); catch( InterruptedException e ) { takechopsticks(); notifyall(); private void takechopsticks() { setleftchopstick( true ); setrightchopstick( true ); seteat( true ); host.dumpstatus(); private void eat() { pause(); seteat( false ); releasechopsticks(); private void think() { pause(); Výpisy Poznámky Třída Philosopher 56

private void pause() { settimeslice( host.generatetimeslice() ); try { sleep( ts * 1000 ); catch ( InterruptedException e ) { private void seteat( boolean f ) { iseating = f; public boolean geteat() { return iseating; Výpisy Poznámky Třída Philosopher 57