12 Metaprogrammering i Java (Litteratur: se sista sidan)

Slides:



Advertisements
Liknande presentationer
Interface.  Interface är en datatyp och har alltså egen syntax och en hel del egna regler för vad arv från interface innebär.  Interface är renodlad.
Advertisements

Avlusning Debugger (”avlusare”) Breakpoints Watch.
Klasser och objekt.
Next previous Internetprogrammering 2000 Internetprogrammering 2000 Föreläsning 10 Distribuerad programmering med Javas RMI, Remote Method Invocation.
OOP Objekt-orienterad programmering
ObjektOrienterad analys och design. SVP Vt2009 Föreläsning nr 2, måndag 8 april kl Diskussion (kurshemsida): Om designuppgiften Om projektuppgiften.
Metoder i java Det finns två typer av metoder i java
Polymorfism.
Programmeringsteknik för K och Media
Föreläsning 13 Allt om tentan. Sistaminutenhjälp: På fredag 17 december kl 12 sitter Linda i kemi-fiket och svarar på frågor.
Programkodens uppbyggnad
Att programmera i språket Java
Next previous Introduktion till Java Av Björn Eiderbäck Adress: Rum 1641, 6tr NADA Osquars Backe 2 Tel: OOMPAE 2000.
1 Föreläsning 6 Klass Object, instans av klass public/private Klassvariabler och klassmetoder.
Alice in Action with Java
i olika programmeringsspråk
Föreläsning 13 Polymorfism, Paket och JAR-filer. Polymorfism Ordet härstammar från grekiskan Poly – många Morf – form Polymorf – många former Någonting.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 7 ( ) INNEHÅLL: -Klasser och instansvariabler -Tabeller av klassobjekt.
Objektorienterad programmering i Java
OOP F4:1 Marie Olsson OOP Objekt-orienterad programmering Föreläsning 4 Metoder klass-metoder instans-metoder.
Programmering i C# 3. Klasser.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 6 ( ) INNEHÅLL: -Mera om tabeller.
Klasser och objekt Klasser, objekt och instansvariabler
Sid 41 Fordon int antalhjul; int vikt;
int res2=Math.max(tal1,tal2);
Föreläsning 2 Kort Översikt Över Javaspråket. Källkodsformat Unicode används åäöμψζ tillåtna Inte alla miljöer klarar av det Källkod Bytekod Java VM för.
Vektorer (klassen Vector) Sortering
Mer om arv - Polymorfism Kursbok: “Objects First with Java - A Practical Introduction using BlueJ”, David J. Barnes & Michael Kölling Fredric Ragnar
Programmering i C# 5. Structer.
Objektorienterad Modellering Programmering och Analys
1. En infrastruktur för programutveckling
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 7 ( ) INNEHÅLL: -Klasser -Att definiera egna klasser -Klassvariabler -Klassmetoder.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 7 ( ) INNEHÅLL: -Metoder -Lokala variabler -Mera om klasser: -Nyckelorden.
Riktade listor i C och Java Lösning till gruppövning 1.
1 Föreläsning 6 Programmeringsteknik och Matlab 2D1312/2D1305 Metoder & parametrar Array API och klassen ArrayList.
Next previous RMI, Remote Method Invocation Om du har boken av Marty Hall, läs avsnitt 15.8 För fler exempel se:
Föreläsning 1 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
Föreläsning 9 Gränssnitt. Super Super kan användas till anrop av en omdefinierad metod Super kan användas till anrop av konstruktorer i superklassen Super.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 5 ( ) INNEHÅLL: -Metoder.
Föreläsning 12 Om slutprovet. Repetition –deklaration av variabler –skapande av objekt (instansiering) –Vektorer och Vector-klassen –Klasser –Instans-/klassvariabler.
Föreläsning 4 Klasser Och Objekt.
1. Ett problem/uppgift.
Föreläsning 4 programmeringsteknik och Matlab 2D1312/ 2D1305
Föreläsning 1 Om kursen Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
ITK:P1 Föreläsning 2 Introduktion till objektorientering DSV Marie Olsson.
Föreläsning 9 Arv kap 8.1 Interface kap 9.2 Grafiska användargränssnitt (GUI) kap 10.
Arv repetition Arv = Är relation Tillgänglighet public, protected och private. Överklass ös Direkt härledd underklass dhu: Class dhu : public ös{} Indirekt.
Programmering i C# Laborationer.
Föreläsning 17 Repetition. Källkodsformat Unicode används åäöμψζ tillåtna i namn på identifierare Inte alla miljöer klarar av det Källkod Bytekod Java.
OOP F5:1 Stefan Möller OOP Objekt-orienterad programmering Föreläsning 5 Klasser och objekt Skapa objekt - new Referenser Konstruktorer Inkapsling.
Övning2 programmeringsteknik och Matlab 2D1312/ 2D1305
Föreläsning 5 Objekt Klasser Konstruktorer Metoder Minnesbilder av objekt.
Programmeringsteknik för K och Media
Föreläsning 5 Klasser och instanser
1 Föreläsning 2 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
1 Föreläsning 4 Metoder & parametrar Array API och klassen ArrayList.
OOP&M - teori1 OOPM del II– Föreläsning vecka Mer om ärvning.. Abstrakta klasser/metoder Gränssnitt/Interface klasser.
DA7351 Programmering 1 Skapa och placera en komponent i en container Layoutmanagers Applet Händelser och lyssnare Föreläsning 15.
1 Mer om metoder, variabler, klasser och objekt. Kursboken: - Kapitel 6 - Kapitel 8.
Gruppövning Applikationsprogramering Klassuppdelning Loose Coupling Model View Controller Inversion of Control Layout med Swing JSplitPane Mouse-over Events.
RMI Av: Josefina & Sarah DS04.
Föreläsning 3: Booleans, if, switch
Föreläsning 6: Metoder och fält (arrays)
Föreläsning 4: for, while, do-while
Föreläsning 8: Exempel och problemlösning
Föreläsning 12: Exempel och problemlösning
Föreläsning 2: Typer, klasser, tilldelning
Föreläsning 9: Arv och UML
Föreläsning 5: Att använda klasser & objekt
Algoritmer och datastrukturer, förel. 1
Presentationens avskrift:

12 Metaprogrammering i Java (Litteratur: se sista sidan) Reflektion, introspektion, metaprogrammering Reflektion i Java Klassladdning Tillämpningar  Flexibilitet  Utbyggbarhet  ”Plugginbarhet” Polymorfism är bra: minskar kopplingen mellan klasser Vi vill driva det ett steg längre! Minska kopplingen mellan applikationer och komponenter. Plug and pray © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Vad handlar det om? Så här får man väl inte göra? String MinTyp = ”int”; MinTyp i; ... eller får man det? … och vad skulle det vara bra för? Svar: 1) Ja i princip. 2) Tveksamt i det här fallet, men … © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Detta! Så här får man göra (något förenklat): String MinTyp = ”Klassnamn”; Class cl = laddaKlass(MinTyp); Object obj = cl.görObjekt(); obj.metod(); komponentbaserad programmering en applikation kan använda nya klasser som tillkommer efter kompileringen av applikationen minimal koppling mellan applikationer och komponenter Namnet på klassen kan givetvis bli känt först under exekveringen © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Reflektiv programmering Reflektion i programmering är förmågan hos ett program att använda eller modifiera sin egen kod eller kod i omgivningen synonym: metaprogrammering, introspektion använda en sträng under exekveringen som om innehållet vore källkod konvertera en sträng som matchar det symboliska namnet på en klass eller metod till en referens till klassen, eller anrop av metoden När ett programmeringsspråk stöder reflektiv programmering sparas typinformation i källkoden tillsammans med den kompilerade koden (.class-filen i Java) I Java representeras (reflekteras) sådan information under exekveringen i objekt av speciella metaklasser Ex. klassen Game reflekteras av ett objekt av metaklassen Class Java, LISP, APL, Eiffel, div. scriptspråk © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Användningsområden Enterprise Computing (storskaligt) Java Beans, RMI (Remote Method Invokation) manipulering av objekt med mjukvaruverktyg verktyget använder reflektion för att analysera eller ändra egenskaper hos dynamiskt laddade komponenter Designmönster (småskaligt) generella factory-klasser generella lyssnare m.m. Reflektion förenklar designmönster och minskar kopplingen ytterligare © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Hantering av typinformation i Java I Java finns flera metoder för att hantera typinformation under exekveringen instanceof Klassliteraler Ex. int.TYPE, Command.class ger ett klassobjekt av typen Class som reflekterar typen Reflektion © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Hantering av typinformation i Java Med instanceof kan man testa den dynamiska typen hos ett objekt if ( cmd instanceof GoCommand ) ((GoCommand)cmd).execute(); else if ( puh! … många fall blir det … Kräver att klassen är känd vid kompileringen eftersom klassen måste namnges Klasshierarkin avspeglas strukturellt i koden Förändringar i hierarkin kräver motsvarande förändringar i koden Detta gäller även interface Fallanalyssyndromet switch-satser … © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Hantering av typinformation i Java Ex. void printClassName(Object obj) { System.out.println("The class of " + obj + " is " obj.getClass().getName()); } System.out.println("The name of class Foo is:" + Foo.class.getName()); © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

- hur kan man använda en okänd klass? Reflektion i Java den flexibla metoden – reflektion! reflekterade klasser kan vara okända vid kompileringen laddas dynamiskt under exekveringen typkontroll sker även här, men vid run-time - hur kan man använda en okänd klass? Helst vill man ha typkontroll vid kompileringen. Vid reflektion hanteras typfel vid run-time med undantag © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Hur kan man använda en okänd klass? Utanför applikationen (komponenter): Definiera ett gränssnitt, t.ex. public interface Command { public void execute(); } Definiera subklasser till Command antag att gränssnittet Command är känt i applikationen, men inte subklasserna med Javas reflektionsmekanism kan subklasserna användas i applikationen, trots att de ej är kända där vid kompileringen Fördel: Programmet kan frikopplas från klasshierarkin nya subklasser kräver ej omkompilering av applikationen D.v.s. frikopplas från alla klasser utom interfacen. © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Hur kan man använda en okänd klass? Inuti applikationen: Ladda någon av de okända subklasserna String klassnamn; ... laddade_subklassen = laddaKlass(klassnamn); Skapa ett objekt av den laddade klassen laddade_subklassen objektet; Typomvandla till Command: Command obj = (Command)objektet; obj.execute(); Alltså: Den laddade klassens namn måste förstås anges vid laddningen, men namnet behöver inte vara känt vid kompileringen, det räcker om det är känt vid run-time! Man måste ju veta vad den heter förstås! © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Klassladdning En klass laddas under exekveringen av JVM (Java Virtual Machine) från en .class-fil när ett objekt av klassen används första gången. För varje klass som laddas av JVM skapas ett motsvarande objekt av metaklassen Class som beskriver (reflekterar) den laddade klassen. Objektet innehåller bl.a. klassens statiska variabler. Laddning sker tidigt om klassen har statiska medlemmar. Man kan ha olika klassladdare. © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Dynamisk klassladdning Applikation Externa komponenter Klassnamn.class leta upp ”Klassnamn” ladda Class klassobjekt instansiera objekt använd objekt.metod(); © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Javas metaklasser Class Constructor Method Field Modifier Array objekt av denna klass reflekterar klasser och interface Constructor ... reflekterar konstruktorer Method ... reflekterar metoder Field … reflekterar attribut Modifier … reflekterar accessmodifierare, public, static, m.m. Array … reflekterar fält Fält hanteras lite speciellt. Två fälltyper är lika om de beskriver fältobjekt av samma längd och med samma elementtyp © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

java.lang.Class getMethods() ger alla metoder, även ärvda Metoder (i urval) Förklaring static Class forName(String className) laddar klassen eller gränssnittet med namnet className och returnerar dess klassobjekt Constructor getConstructor( Class ... parameterTypes) ger ett konstruktorobjekt med angivna parametertyper Method getMethod(String name, Class ... parameterTypes) ger en metodobjekt med angivna parametertyper Field getField(String name) ger ett variabelobjekt med angivet namn Object newInstance() skapar ett objekt av klassen som reflekteras av detta klassobjekt getMethods() ger alla metoder, även ärvda getDeclaredMethods() ger bara de som definierats i den aktuella klassen Varargs: Skansholm s.316 int f(int … a) { int sum = 0; for ( int x : a ) sum += x; return sum; } Anrop: f(1); f(1,2); f(32,7,-3,9); int f(int[] a) { int sum = 0; for ( int x : a ) sum += x; return sum; © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Varargs = variabla argument I Java finns en möjlighet att skriva metoder som tar ett variabelt antal argument. Ex int f(int ... a) { int sum = 0; for ( int x : a ) sum += x; return sum; } Ex. på anrop: f(1); f(1,2); f(45,-17,99) Ekvivalent kod int f(int[] a) { int sum = 0; for ( int x : a ) sum += x; return sum; } … översätts till ett fält i metoden Kan anropas med både enstaka argument och fält. © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

java.lang.reflect.Constructor Metoder (i urval) Förklaring Class getDeclaringClass() ger klassobjektet för klassen som deklarerar konstruktorn som reflekteras av detta konstruktorobjekt Class[] getParametertypes() ger ett fält av klassobjekt som reflekterar de formella parametrarna till konstruktorn som … Class[] getExceptionTypes() ger ett fält med alla undantag som kan kastas av konstruktorn String getName() ger konstruktorns namn Hela tiden avses ”den underliggande metoden som representeras av detta metodobjekt” © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

java.lang.reflect.Method Metoder (i urval) Förklaring Object invoke(Object o,Object ...args) anropar metoden som representeras av detta metodobjekt för objektet o och med parametrarna args Class[] getParametertypes() ger ett fält av klassobjekt som represen- terar de formella parametrarna Class getReturntype() ger metodens returtyp Class[] getExceptionTypes() ger ett fält med alla undantag som kan kastas av metoden String getName() ger metodens namn Invoke returnerar null om den underliggande metoden returnerar void Hela tiden avses ”den underliggande metoden som representeras av detta metodobjekt” © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Exempel  Namn- och metodnamn är låsta // Utan reflektion Klassnamn objekt = new Klassnamn(); objekt.metod(); // Med reflektion Class klassobjekt = Class.forName("Klassnamn"); Method metod = klassobjekt.getMethod("metod",parametertyper); Object objekt = klassobjekt.newInstance(); metod.invoke(objekt,parametrar);  Namn- och metodnamn är låsta  Typkontroll vid kompileringen  Hög läsbarhet  Namn- och metodnamn kan variera under exekveringen  Typkontroll under exekveringen (exceptions)  Lägre läsbarhet Ja här är ju namnet hårdkodat med en strängkonstant, men det kunde varit en variabel! © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Exempel 1: commandFactory public interface Command { public void execute(); } public class Take implements Command { public void execute() { // do whatever + Go, Stop, Turn, Quit, etc. Ett något mer utvecklat exempel finns i gamecharacters Detta kan användas i spelet © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

commandFactory public void processCommand(String commandName) { Command command = getFactoryCommand(commandName); command.execute(); } public static Command getFactoryCommand(String s) { Command command = null; try { // Load the class with name s and instantiate it command = (Command) Class.forName(s).newInstance(); } catch (Exception e) { e.printStackTrace(); return command; Ex. String cmd; ... processCommand(cmd); DEMO: Lägg till klassen Quit. Main behöver inte kompileras om! Här antas att klasserna har parameterlösa konstruktorer © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Exempel2: Metoder med parametrar public class C { public void f(Integer i) { ... } public void f(String s) { ... } } ... Class cls = Class.forName("C"); Method m = cls.getMethod("f",String.class); Object obj = cls.newInstance(); m.invoke(obj,"Hej!"); DEMO: Lägg till klassen Quit. Main behöver inte kompileras om! Här antas att klasserna har parameterlösa konstruktorer © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Exempel 3: Generell lyssnare public class Main extends JFrame implements ActionListener { public Main() { ... JButton plingButton = new JButton("pling"); plingButton.setActionCommand("pling"); plingButton.addActionListener(this); add(plingButton); JButton plongButton = new JButton("plong"); plongButton.setActionCommand("plong"); plongButton.addActionListener(this); add(plongButton); JButton klonkButton = new JButton("klonk"); klonkButton.setActionCommand("klonk"); klonkButton.addActionListener(this); add(klonkButton); } ... forts. DEMO: Visa ev. alla tre varianterna © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Generell lyssnare Här borde de tre metoderna överst flyttas ut … ... public void pling() { ... } public void plong() { ... } public void klonk() { ... } // General listener using reflection public void actionPerformed(ActionEvent ev) { try { this.getClass(). getMethod(ev.getActionCommand()). invoke(this); } catch (Exception e) { e.printStackTrace(); Här borde de tre metoderna överst flyttas ut … © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Generell lyssnare this.getClass(). getMethod(ev.getActionCommand()). invoke(this); ger klassobjektet för detta objekt ger namnet på händelseobjektets action-metod (”pling”, ”plong” eller ”klonk”) Reflekterar action-metodnamnet på ett metodobjekt som reflekterar metoden med detta namn. Ex. ”plong” reflekteras på metoden plong() Anropar den reflekterade metoden för detta objekt © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12

Litteratur Den andra bifogas i OH-bunten http://docs.oracle.com/javase/tutorial/reflect/index.html En introduktion till javas reflektions-API. Portwood, Michael, Using Java Reflection Technology to Improve Design, Den finns på kurshemsidan (… men var kom originalet ifrån?) En samling OH-bilder som ger en bra översikt. Neward, Ted, Understanding Class.forname(), http://www.idevelopment.info/data/Programming/java/reflection/Understanding_ClassForName.pdf En grundlig genomkörare för den som ämnar ge sig på avancerad komponentbaserad programmering. Tar bl.a. upp problemet med olika klassladdare och CLASSPATH i samband med Extensions m.m. Den andra bifogas i OH-bunten © Uno Holmer, DIT, Chalmers, 2018-09-16 www.cse.chalmers.se/~holmer/ Objektorienterade applikationer d2, förel. 12