Reflexe (programování)

Technology
12 hours ago
8
4
2
Avatar
Author
Albert Flores

Reflexe je v objektově orientovaném programování schopnost programovacího jazyka zjistit za běhu informace o určitém programovém objektu. Obecně v programování je reflexe schopnost zjistit informace o programu a jeho syntaktické struktuře.

V objektově orientovaném programování je program rozdělen do tříd, kdy jednotlivá třída popisuje vnitřní strukturu objektu a jeho vnější rozhraní. Na základně tříd je možné tvořit jednotlivé objekty. +more Některé jazyky mají schopnost za běhu zjistit informace o daném programu. Tato schopnost se nazývá reflexe, s jejíž pomocí lze získat za běhu programu informace o typu objektu. V objektově orientovaném programování se dá říci, že vše je objekt, tak je tedy objektem i třída a jiné datové typy, o kterých lze zjistit požadované informace.

Využití

Schopnost reflexe je vhodná pro vzdálené zpracování, kdy jsou dva počítače a na jeden z nich přicházejí objekty z toho druhého a počítač, který objekty zpracovává, má možnost získat pomocí reflexe potřebné informace o daném typu objektu. Lze to využít v jakémkoli programu, který za běhu upravuje své chování vůči objektům, se kterými pracuje.

Reflexe v Javě

Informace, které potřebujeme, můžeme získat z instance třídy java. lang. +moreClass. Tento class-objekt mají jak třídy, tak rozhraní i primitivní typy. Při zavádění daného typu do paměti je pomocí instance třídy ClassLoader vytvořen class-objekt, který lze využít při získávání informací o daném typu objektu. Pokud je nutné zajistit dynamické chování programu, v tomto případě je vhodnější využít jazyky jako Groovy, Jython, JRuby, jejichž překladače řeší dynamičnost pomocí reflexe. V případě, že se liší jednotlivé verze JVM svými knihovnami, pak je možné přizpůsobit chování programu verzi virtuálního stroje, na kterém aktuálně program běží.

Za běhu programu je možné získat: * Název typu * Druh typu (interface, třída, výčtový typ) * Anotace * Atributy, konstruktory, metody a vnořené datové typy

S těmito informacemi získanými za běhu programu je následně možné například volat konstruktory, metody nebo zjišťovat a přiřazovat hodnoty atributů. Lze také zjistit informace o nedostupných členech, ale v běžných situacích k nim není přístup.

Získání existujícího class-objektu

Pokud je typ daného názvu již zaveden do paměti, tak je vrácen jeho class-objekt a nevytváří se nový.

Pokud známe typ objektu a nemáme jeho instanci, pak literálem Typ. class private Class clazz = Color. +moreclass; Field [] fields = clazz. getDeclaredFields; //získání všech deklarovaných proměnných ze třídy.

U každého objektu lze volat metodu getClass, díky čemuž jsme schopni zjistit, jaké třídy je objekt instancí. Trida trida = new Trida; trida. +moregetReflection. getAnnotations; //získá anotace dané třídy.

Získání class-objektu datového typu zadaného svým názvem

Pomocí statické metody Class. forName(String) lze získat class-objekt typu se zadaným úplným názvem, tj. +more včetně názvu balíčku. Při použití modulů lze volánímClass. forName(Module, String) požádat o class-objekt zadaného typu v zadaném modulu. Rozšířené možnosti nabízí metoda Class. forName(String, boolean, ClassLoader), jejíž druhý parametr zadává, zda má být daný typ inicializován, a třetí parametru specifikuje ClassLoader, který má daný datový typ zavést. Class. forName("java. lang. String"); Class. forName("Foo",true,this. getClass. getClassLoader);.

Reflexní metody třídy Class v Javě

Třída Class definuje 71 metod, z toho jen 3 statické (forName(?));

Metody pro získání konstruktorů

Statický inicializátor (tj. konstruktor třídy) není možné získat. +more Získat lze pouze konstruktory instancí. Constructor getConstructor(Class. parameterTypes) Constructor getDeclaredConstructor(Class. parameterTypes).

Metody pro získání polí

U polí se zadává jenom název. Field getField(String name) Field getDeclaredField(String name)

Metody pro získaní metod

Method getMethod(String name, Class... parameterTypes) throws NoSuchMethodException, SecurityException

Všechny veřejné metody včetně zděděných

Method[] getMethods throws SecurityException

Všechny s výjimkou zděděných

Method[] getDeclaredMethods throws SecurityException Metody pro získání názvu: String getSimpleName String getName String toString

Metody pro získání informací o daném druhu typu, reprezentovaném class-objektem

isAnnotation, isAnonymousClass, isArray, isEnum, isInterface, isLocalClass, isMemberClass, isPrimitive, isSynthetic

Ostatní informace o typu

getPackage, int getModifiers, Class getSuperclass, Class getComponentType

Metody vracející reprezentanty veřejných členů

Constructor[] getConstructors Field[] getFields Method[] getMethods Class[] getClasses Annotation[] getAnnotations

Metody vracející reprezentanty deklarovaných členů

Vrací soukromé členy, ale nevrací zděděné členy. Constructor[] getDeclaredConstructors Field[] getDeclaredFields Method[] getDeclaredMethods Class[] getDeclaredClasses Annotation[] getDeclaredAnnotations

Reflexe v C#

Jmenný prostor, který umožňuje v . NET používat reflexi se jmenuje System. +moreReflection. Základní cestou k metadatům typu v mechanismu reflexe je třída získat instanci třídy System. Type. Díky ní je možné získat rozličné informace o daném typu, včetně seznamu jeho členů. Může se tak udělat pomocí metody GetType nebo pomocí operátoru typeof. Type t = Type. GetType("System. Int32"); Type t2 = Type. GetType("MyNamespace. MyType", MyAssembly); Type t3 = typeof(System. Int32); Rozdíl mezi těmito dvěma druhy je v tom, že GetType se vyhodnocuje za běhu, zatímco operátor typem v době kompilace. Máme-li instanci třídy Type, máme přístup k metadatům, atributům nebo vytvářet nové instance typů. Vztahy mezi dědičnosti mezi reflexními typy . NET.

Ve chvíli, kdy máme odkaz na některý z těchto elementů, tak můžeme pohybovat se vztahy mezi daným elementem a souvisejícími prvky, jak je uvedeno na následujícím obrázku.

Nejzákladnějším typem reflexe je v . NET třída Type. +more Reprezentuje metadata pro jednotlivé deklarace typů v aplikaci. Typy obsahují členy. Ty zahrnují konstruktory, proměnné, vlastnosti, události a metody. Typy mohou navíc obsahovat vnořené typy, které se typicky používají jako pomocné třídy. Typy jsou seskupené do modulů a moduly jsou obsažené v sestavách.

Reflexe v PHP

Od 5. verze tohoto jazyka, kdy se přišlo s objekty, má PHP základní schopnost reflexe, avšak ne dostatečnou, proto se různé frameworky snaží o její rozšíření. +more O reflexi v tomto jazyce se stará třída Reflection. V základním PHP například nemůžeme zjistit nic o anotacích daného objektu.

$a = new A; $reflector = new ReflectionClass('A'); //vezme všechny vlastnosti třídy A a uloží je do pole $properties = $reflector->getProperties;

Nette

Nette\Object usnadňuje i přístup k sebereflexi třídy pomocí metody getReflection, která vrací objekt třídy ClassType.

$circle = new Circle; echo $circle->getReflection->hasMethod('getArea'); // existuje metoda 'getArea' ? echo $circle->getReflection->getName; // vrací název třídy, tj. 'Circle'

Zend

Zend_Reflection_Class dědí od základní třídy Reflection a přidává další funkčnost.

$r = new Zend_Reflection_Class($class); printf( "The class level docblock has the short description: %s\n". "The class level docblock has the long description:\n%s\n", $r->getDocblock->getShortDescription, $r->getDocblock->getLongDescription); // Get the declaring file reflection $file = $r->getDeclaringFile;

Reflexe v Objective-C

// Foo třída @interface Foo : NSObject - (void)hello; @end // bez reflexe Foo *obj = [[Foo alloc] init]; [obj hello]; // s reflexí id obj = [[NSClassFromString(@"Foo") alloc] init]; [obj performSelector: @selector(hello)];

Reflexe v Ruby

# bez reflexe obj = Foo.new obj.hello # s reflexí class_name = "Foo" method = :hello obj = Kernel.const_get(class_name).new obj.send method

Reflexe v Perlu

# bez reflexe my $foo = Foo->new; $foo->hello; # nebo Foo->new->hello;

s reflexí

my $class = "Foo" my $constructor = "new"; my $method = "hello"; my $f = $class->$constructor; $f->$method; # nebo $class->$constructor->$method;

Reflexe ve Visual Basic

' Využití GetType k získání informací o daném typu: Dim i As Integer = 42 Dim type As System. Type = i. +moreGetType System. Console. WriteLine(type) ' Využití reflexe k získání informací z Assembly: Dim info As System. Reflection. Assembly = GetType(System. Int32). Assembly System. Console. WriteLine(info) ' Využití GetType k získání informací o daném typu: Dim i As Integer = 42 Dim type As System. Type = i. GetType System. Console. WriteLine(type) ' Využití reflexe k získání informací z Assembly: Dim info As System. Reflection. Assembly = GetType(System. Int32). Assembly System. Console. WriteLine(info).

5 min read
Share this post:
Like it 8

Leave a Comment

Please, enter your name.
Please, provide a valid email address.
Please, enter your comment.
Enjoy this post? Join Cesko.wiki
Don’t forget to share it
Top