• Nenhum resultado encontrado

Tehnici avansate de programare

N/A
N/A
Protected

Academic year: 2023

Share "Tehnici avansate de programare"

Copied!
35
0
0

Texto

(1)

Tehnici avansate de programare

Curs -

Cristian Fr ˘asinaru

acf@infoiasi.ro

Facultatea de Informatic ˘a Universitatea ”Al. I. Cuza” Ias¸i

(2)

Lucrul dinamic cu clase

Tehnici avansate de programare – p.1/36

(3)

Cuprins

Incarcarea claselor în memorie Reflection API

Examinarea claselor ¸si interfe¸telor Lucrul dinamic cu obiecte

Lucrul dinamic cu vectori Crearea proceselor *

Tehnici avansate de programare – p.2/36

(4)

Inc˘arcarea claselor în memorie

Tehnici avansate de programare – p.3/36

(5)

Ciclul de via¸t˘a al unei clase

1. Inc ˘arcarea în memorie - va fi instan¸tiat un obiect de tip java.lang.Class .

2. Editarea de leg ˘aturi - incorporarea noului tip de date în JVM.

3. Ini¸tializarea - execu¸tia blocurilor statice de ini¸tializare ¸si ini¸tializarea variabilelor de clas ˘a.

4. Desc ˘arcarea - Atunci când nu mai exist ˘a nici o referin¸t˘a de tipul clasei respective, obiectul de tip Class creat va fi marcat pentru a fi eliminat din memorie de c ˘atre garbage collector .

Tehnici avansate de programare – p.4/36

(6)

Clasa ClassLoader

1. Class loader-ul primordial (eng. bootstrap) -

Reprezint ˘a o parte integrant ˘a a ma¸sinii virtuale, fiind responsabil cu înc ˘arcarea claselor standard din

distribu¸tia Java.

2. Class loader-e proprii - Acestea nu fac parte intrinsec ˘a din JVM ¸si sunt instan¸te ale clasei

java.lang.ClassLoader . Aceasta este o clas ˘a abstract ˘a, tipul efectiv al obiectului fiind a¸sadar derivat din

aceasta.

Tehnici avansate de programare – p.5/36

(7)

Class loader-e implicite

Boostrap Class Loader - Class loader-ul primordial.

Acesta este responsabil cu înc ˘arcarea claselor din distribu¸tia Java standard (cele din pachetele java.* , javax.* , etc.).

Extension Class Loader - înc ˘arcarea claselor din directoarele extensiilor JRE.

System Class Loader - înc ˘arcarea claselor proprii aplica¸tiilor Java (cele din CLASSPATH). Tipul

acestuia este java.lang.URLClassLoader .

Fiecare obiect Class va re¸tine class loader-ul care a fost folosit pentru înc ˘arcare, acesta putând fi ob¸tinut cu

metoda getClassLoader .

Tehnici avansate de programare – p.6/36

(8)

Modelul "delegat"

Tehnici avansate de programare – p.7/36

(9)

Inc˘arcarea unei clase în memorie

loadClass apelat ˘a pentru un obiect de tip ClassLoader

ClassLoader loader = new MyClassLoader();

loader.loadClass("NumeCompletClasa");

Class.forName

Class c = Class.forName("NumeCompletClasa");

// echivalent cu

ClassLoader loader = this.getClass().getClassLoader();

loader.loadClass("ClasaNecunoscuta");

// Clasele standard pot fi si ele incarcate astfel Class t = Class.forName("java.lang.Thread");

Tehnici avansate de programare – p.8/36

(10)

Instan¸tierea unui obiect

Dac ˘a dorim s ˘a instan¸tiem un obiect dintr-o clas ˘a

înc ˘arcat ˘a dinamic putem folosi metoda newInstance, cu condi¸tia s ˘a existe constructorul f ˘ar ˘a argumente pentru clasa respectiv ˘a.

Class c = Class.forName("java.awt.Button");

Button b = (Button) c.newInstance();

Tehnici avansate de programare – p.9/36

(11)

TestFunctii.java

public class TestFunctii {

public static void main(String args[]) throws IOException { int n=10, v[] = new int[n];

Random rand = new Random();

for(int i=0; i<n; i++) v[i] = rand.nextInt(100);

// Citim numele unei functii

BufferedReader stdin = new BufferedReader(

new InputStreamReader(System.in));

String numeFunctie = "";

while (! numeFunctie.equals("gata")) { numeFunctie = stdin.readLine();

try {

Class c = Class.forName(numeFunctie);

Functie f = (Functie) c.newInstance();

f.setVector(v); // sau f.v = v;

int ret = f.executa();

System.out.println("\nCod returnat: " + ret);

} catch (Exception e) { ... } }

} }

Tehnici avansate de programare – p.10/36

(12)

Functie.java

public abstract class Functie { public int v[] = null;

public void setVector(int[] v) { this.v = v;

}

public abstract int executa();

}

Tehnici avansate de programare – p.11/36

(13)

Diverse func¸tii

Sort.java

public class Sort extends Functie { public int executa() {

if (v == null) return -1;

Arrays.sort(v);

for(int i=0; i<v.length; i++) System.out.print(v[i] + " ");

return 0;

} }

Max.java

public class Max extends Functie { public int executa() {

if (v == null) return -1;

int max = v[0];

for(int i=1; i<v.length; i++) if (max < v[i])

max = v[i];

System.out.print(max);

return 0;

} Tehnici avansate de programare – p.12/36

(14)

Folosirea class loader-ului curent

URLClassLoader

// Obtinem class loaderul curent URLClassLoader urlLoader =

(URLClassLoader) this.getClass().getClassLoader();

// Adaugam directorul sub forma unui URL

urlLoader.addURL(new File("c:\\clase").toURL());

// Incarcam clasa

urlLoader.loadClass("demo.Test");

Tehnici avansate de programare – p.13/36

(15)

Crearea unui class loader nou

public class MyClassLoader extends URLClassLoader{

public MyClassLoader(URL[] urls){

super(urls);

} }

// La initializare

URLClassLoader systemLoader =

(URLClassLoader) this.getClass().getClassLoader();

URL[] urls = systemLoader.getURLs();

// Cream class loaderul propriu

MyClassLoader myLoader = new MyClassLoader(urls);

myLoader.loadClass("Clasa");

...

// Dorim sa reincarcam clasa

myLoader.loadClass("Clasa"); // nu functioneaza ! // Cream alt class loader

MyClassLoader myLoader = new MyClassLoader(urls);

myLoader.loadClass("Clasa"); // reincarca clasa

Tehnici avansate de programare – p.14/36

(16)

Mecanismul reflect˘arii

Tehnici avansate de programare – p.15/36

(17)

Ce înseamn˘a reflection ?

Mecanismul prin care o clas ˘a, interfa¸t˘a sau obiect

"reflect ˘a" la momentul execu¸tiei structura lor intern ˘a se nume¸ste reflectare.

Determinarea clasei unui obiect.

Aflarea unor informa¸tii despre o clas ˘a (modificatori, superclasa, constructori, metode).

Instan¸tierea unor clase al c ˘aror nume este ¸stiut abia la execu¸tie.

Setarea sau aflarea atributelor unui obiect, chiar dac ˘a numele acestora este ¸stiut abia la execu¸tie.

Invocarea metodelor unui obiect al c ˘aror nume este ¸stiut abia la execu¸tie.

Crearea unor vectori a c ˘aror dimensiune ¸si tip nu este ¸stiut decât la execu¸tie.

Tehnici avansate de programare – p.16/36

(18)

Reflection API

java.lang.Class java.lang.Object

Clasele din pachetul java.lang.reflect ¸si anume:

Array

Constructor Field

Method Modifier

Tehnici avansate de programare – p.17/36

(19)

Examinarea claselor ¸si interfe¸telor

Tehnici avansate de programare – p.18/36

(20)

Aflarea instan¸tei Class

Class c = obiect.getClass();

Class c = java.awt.Button.class;

Class c = Class.forName("NumeClasa");

Class clasa = obiect.getClass();

String nume = clasa.getName();

Interfe¸tele sunt tot de tip Class , diferen¸tierea lor f ˘acându-se cu metoda isInterface .

Tipurile primitive sunt descrise ¸si ele de instan¸te de tip Class având forma TipPrimitiv .class : int.class, double.class , etc., diferen¸tierea lor f ˘acându-se cu ajutorul metodei isPrimitive .

Tehnici avansate de programare – p.19/36

(21)

Aflarea modificatorilor unei clase

Metoda getModifiers

Class clasa = obiect.getClass();

int m = clasa.getModifiers();

String modif = "";

if (Modifier.isPublic(m)) modif += "public ";

if (Modifier.isAbstract(m)) modif += "abstract ";

if (Modifier.isFinal(m)) modif += "final ";

System.out.println(modif + "class" + c.getName());

Tehnici avansate de programare – p.20/36

(22)

Aflarea superclasei

Metoda getSuperclass

Returneaz ˘a null pentru clasa Object

Class c = java.awt.Frame.class;

Class s = c.getSuperclass();

System.out.println(s); // java.awt.Window Class c = java.awt.Object.class;

Class s = c.getSuperclass(); // null

Tehnici avansate de programare – p.21/36

(23)

Aflarea interfe¸telor

Metoda getInterfaces

public void interfete(Class c) {

Class[] interf = c.getInterfaces();

for (int i = 0; i < interf.length; i++) { String nume = interf[i].getName();

System.out.print(nume + " ");

} } ...

interfete(java.util.HashSet.class);

// Va afisa interfetele implementate de HashSet:

// Cloneable, Collection, Serializable, Set interfete(java.util.Set);

// Va afisa interfetele extinse de Set:

// Collection

Tehnici avansate de programare – p.22/36

(24)

Aflarea membrilor

Variabile: getFields, getDeclaredFields

→ Field

Constructori: getConstructors, getDeclaredConstructors

→ Constructor

Metode: getMethods, getDeclaredMethods

→ Method

Clase imbricate: getClasses, getDeclaredClasses

getDeclaringClass : clasa c ˘areia îi apar¸tine un membru.

Tehnici avansate de programare – p.23/36

(25)

Manipularea obiectelor

Tehnici avansate de programare – p.24/36

(26)

Crearea obiectelor

Metoda newInstance din clasa java.lang.Class

Class c = Class.forName("NumeClasa");

Object o = c.newInstance();

Metoda newInstance din clasa Constructor

Class clasa = java.awt.Point.class;

// Obtinem constructorul dorit

Class[] signatura = new Class[] {int.class, int.class};

Constructor ctor = clasa.getConstructor(signatura);

// Pregatim argumentele

// Ele trebuie sa fie de tipul referinta corespunzator Integer x = new Integer(10);

Integer y = new Integer(20);

Object[] arg = new Object[] {x, y};

// Instantiem

Point p = (Point) ctor.newInstance(arg);

Tehnici avansate de programare – p.25/36

(27)

Invocarea metodelor

Metoda invoke din clasa Method

Class clasa = java.awt.Rectangle.class;

Rectangle obiect = new Rectangle(0, 0, 100, 100);

// Obtinem metoda dorita

Class[] signatura = new Class[] {Point.class};

Method metoda = clasa.getMethod("contains", signatura);

// Pregatim argumentele

Point p = new Point(10, 20);

Object[] arg = new Object[] {p};

// Apelam metoda

metoda.invoke(obiect, arg);

Tehnici avansate de programare – p.26/36

(28)

Setarea ¸si aflarea variabilelor

Metodele set ¸si get din clasa Field

Class clasa = java.awt.Point.class;

Point obiect = new Point(0, 20);

// Obtinem variabilele membre Field x, y;

x = clasa.getField("x");

y = clasa.getField("y");

// Setam valoarea lui x

x.set(obiect, new Integer(10));

// Obtinem valoarea lui y Integer val = y.get(obiect);

Tehnici avansate de programare – p.27/36

(29)

TestFunctii2.java

Class c = Class.forName(numeFunctie);

Object f = c.newInstance();

Field vector = c.getField("v");

vector.set(f, v);

Method m = c.getMethod("executa", null);

Integer ret = (Integer) m.invoke(f, null);

System.out.println("\nCod returnat: " + ret);

Tehnici avansate de programare – p.28/36

(30)

Lucrul dinamic cu vectori

Vectorii sunt reprezenta¸ti ca tip de date tot prin

intermediul clasei java.lang.Class , diferen¸tierea f ˘acându-se prin intermediul metodei isArray .

Tipul de date al elementelor din care este format vectorul va fi ob¸tinut cu ajutorul metodei getComponentType , ce întoarce o referin¸t˘a de tip Class .

Point []vector = new Point[10];

Class c = vector.getClass();

System.out.println(c.getComponentType());

// Va afisa: class java.awt.Point

Tehnici avansate de programare – p.29/36

(31)

Obiecte de tip vector

Clasa Array

Crearea de noi vectori: newInstance

Aflarea num ˘arului de elemente: getLength Setarea / aflarea elementelor: set , get

Object a = Array.newInstance(int.class, 10);

for (int i=0; i < Array.getLength(a); i++) Array.set(a, i, new Integer(i));

for (int i=0; i < Array.getLength(a); i++) System.out.print(Array.get(a, i) + " ");

Tehnici avansate de programare – p.30/36

(32)

Crearea ¸si comunicarea cu procese externe

Tehnici avansate de programare – p.31/36

(33)

Crearea unui proces

public class TestRuntime {

public static void main(String args[]) throws Exception{

Runtime runtime = Runtime.getRuntime();

Process child = runtime.exec("java Aplicatie");

runtime.exec("cmd.exe /c start help.html");

String[] commands = new String[]{"notepad", "calc"};

runtime.exec(commands);

} }

Tehnici avansate de programare – p.32/36

(34)

Fluxul de ie¸sire al unui proces

String command = "java Aplicatie";

Process child = Runtime.getRuntime().exec(command);

// Citim de pe fluxul de iesire al procesului InputStream in = child.getInputStream();

int c;

while ((c = in.read()) != -1) { // proceseaza c

}

in.close();

Tehnici avansate de programare – p.33/36

(35)

Fluxul de intrare al unui proces

String command = "java Aplicatie";

Process child = Runtime.getRuntime().exec(command);

// Scriem pe fluxul de intrare al procesului OutputStream out = child.getOutputStream();

out.write("some text".getBytes());

out.close();

Tehnici avansate de programare – p.34/36

Referências

Documentos relacionados

doi: 10.24365/ef.v60i4.484 Kulcsszavak: helytelen táplálkozás; bolygónk egészsége; klímaváltozás; gazdasági teher Keywords: malnutrition; planetary health; climate change; economic