Reflectie is de programmeertaal Java een van de kenmerken, die Java-programma's kunnen draaien op hun eigen inspecties of "self-onderzoek," en kunnen direct toeschrijven aan de interne operationele procedures.Bijvoorbeeld, kan het een Java-class naam van elk lid en weer te geven.
Java, in de praktische toepassing van deze mogelijkheid gebruik kan worden gebruikt, zijn niet veel, maar in andere programmeertalen deze functie simpelweg niet bestaat.Bijvoorbeeld, Pascal, C of C + +, is er geen manier om de functie-definitie in de programma-informatie te krijgen.
JavaBean is een weerspiegeling van de praktische toepassing, laat visualisatie tools die software componenten.Deze tools worden dynamisch geladen door middel van reflectie en krijg Java-componenten (klassen) van het pand.
1. Een eenvoudig voorbeeld
Beschouw het volgende eenvoudig voorbeeld, laat ons zien hoe het werk reflectie.
import java.lang.reflect .*;
public class DumpMethods {
public static void main (String args []) {
try {
Klasse C = Class.forName (args [0]);
Methode m [] = c.getDeclaredMethods ();
for (int i = 0; i m.length; i + +)
System.out.println (m [i] ToString ().);
} Catch (Throwable e) {
System.err.println (e);
}
}
}
Statement wordt uitgevoerd als volgt:
java DumpMethods java.util.Stack
Het is de resulterende output is:
openbare java.lang.Object java.util.Stack.push (java.lang.Object)
openbare gesynchroniseerd java.lang.Object java.util.Stack.pop ()
openbare gesynchroniseerd java.lang.Object java.util.Stack.peek ()
openbare boolean java.util.Stack.empty ()
openbare gesynchroniseerd int java.util.Stack.search (java.lang.Object)
Dit geeft de naam van elke methode java.util.Stack klasse en hun kwalificatie en de terugkeer type.
Dit programma maakt gebruik van Class.forName aan de opgegeven klasse dan laden, getDeclaredMethods oproep om deze klasse te krijgen in een methode die lijst.java.lang.reflect.Methods wordt gebruikt om een enkele methode van een klasse van een klasse te beschrijven.
2. Gestart Reflectie
Voor de reflectie van de klasse, zoals de methode kan worden gevonden in de java.lang.relfect pakket.Bij het gebruik van deze klassen moeten volgen drie stappen: De eerste stap is om de klasse die u wilt java.lang.Class object werken.Hardlopen in het Java-programma, met de java.lang.Class klasse voor de klassen en interfaces te beschrijven.
Hier is het verkrijgen van een klasse-object methoden:
Klasse C = Class.forName ("java.lang");
Deze verklaring een String klasse klasse object.Er is een andere manier, zoals de volgende verklaring:
Klasse C = int.class;
Of
Klasse C = Integer.TYPE;
Zij ontvangen basistypen van klasse informatie.Bezoek een van de laatste methode is het basistype voor pakket (zoals Integer) in de pre-gedefinieerde type veld.
De tweede stap is om de methode aan te roepen, zoals getDeclaredMethods om alle methoden die zijn gedefinieerd in de klasse lijst.
Zodra u deze informatie verkregen, kan de derde stap worden uitgevoerd - en het gebruik van de reflectie API om de informatie, zoals de volgende code te manipuleren:
Klasse C = Class.forName ("java.lang");
Methode m [] = c.getDeclaredMethods ();
System.out.println (m [0] ToString ().);
Het zal uit te printen als tekst String methode gedefinieerd in het eerste prototype.
In het onderstaande voorbeeld, de drie stappen voor het omgaan met specifieke toepassingen tot reflectie te gebruiken om voorbeelden te geven.
Analoge operator instanceof
Na je klas informatie, meestal de volgende stap is om op te lossen op de klasse-object van een aantal elementaire zaken.Kan bijvoorbeeld Class.isInstance methode worden gebruikt om de simulatie van de operator instanceof:
klasse A {
}
public class Instantie1 {
public static void main (String args []) {
try {
Class = cls Class.forName ("A");
boolean b1 = cls.isInstance (nieuw Integer (37));
System.out.println (b1);
boolean b2 = cls.isInstance (nieuwe A ());
System.out.println (b2);
} Catch (Throwable e) {
System.err.println (e);
}
}
}
In dit voorbeeld wordt een klasse van klasse A voorwerpen, en vervolgens controleren of een object is een instantie van A.Integer (37) is het niet, maar de nieuwe A () is.
3. Om methoden van de klasse te vinden
Zoek een klasse definieert welke methoden, is dit een zeer waardevol gebruik van zeer fundamentele reflectie.De volgende code doet dit gebruik:
import java.lang.reflect .*;
public class methode1 {
private int f1 (Object p, int x) {gooit NullPointerException
if (p == null)
throw new NullPointerException ();
terug x;
}
public static void main (String args []) {
try {
Class = cls Class.forName ("methode1");
Methode methlist [] = cls.getDeclaredMethods ();
for (int i = 0; i methlist.length; i + +) {
Methode m = methlist [i];
System.out.println ("naam =" + m.getName ());
System.out.println ("decl class =" + m.getDeclaringClass ());
Klasse pvec [] = m.getParameterTypes ();
for (int j = 0; j pvec.length; j + +)
System.out.println ("param #" + j + "" + pvec [j]);
Klasse 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);
}
}
}
Dit programma eerst een beschrijving van methode1 klasse, bel dan getDeclaredMethods tot een reeks van methode objecten, die zijn gedefinieerd in de klasse te beschrijven elk van de methoden, met inbegrip van openbare methoden, beschermd en-methoden,-pakket prive-methoden en-methoden te verkrijgen.Als u het programma gebruiken om getMethods getDeclaredMethods vervangen, kunt u alle geërfd methoden.
Methode om een lijst van objecten te verkrijgen, om de parameters van deze methoden blijkt het type uitzondering typen en terug te keren waarde van soorten niet moeilijk.Deze types zijn de basis type-of klasse type, kunnen beschrijven de klasse van objecten door de aangegeven volgorde.
De output is als volgt:
naam = f1
decl class = klasse methode1
param # 0 klasse java.lang.Object
param # 1 int
exc # 0 klasse java.lang.NullPointerException
return type = int
-----
naam = belangrijkste
decl class = klasse methode1
param # 0 klasse [Ljava.lang.String;
return type = ongeldig
4. Get constructor informatie
Klasse constructor voor het gebruik van het bovenstaande voor het gebruik van soortgelijke methoden, zoals:
import java.lang.reflect .*;
public class constructor1 {
openbare constructor1 () {
}
beschermd constructor1 (int i, dubbel d) {
}
public static void main (String args []) {
try {
Class = cls Class.forName ("constructor1");
Constructor ctorlist [] = cls.getDeclaredConstructors ();
for (int i = 0; i ctorlist.length; i + +) {
Constructor ct = ctorlist [i];
System.out.println ("naam =" + ct.getName ());
System.out.println ("decl class =" + ct.getDeclaringClass ());
Klasse pvec [] = ct.getParameterTypes ();
for (int j = 0; j pvec.length; j + +)
System.out.println ("param #" + j + "" + pvec [j]);
Klasse Evec [] = ct.getExceptionTypes ();
for (int j = 0; j evec.length; j + +)
System.out.println ("exc #" + j + "" + Evec [j]);
System.out.println ("-----");
}
} Catch (Throwable e) {
System.err.println (e);
}
}
}
Dit geval niet terug te krijgen van de aard van de informatie, is het omdat de aannemer niet terugkeren.
Het resultaat van de lopende:
naam = constructor1
decl class = klasse constructor1
-----
naam = constructor1
decl class = klasse constructor1
param # 0 int
param # 1 dubbel
5. Voor de klasse veld (domein)
Zoek een klasse definieert welke gegevens velden ook mogelijk zijn, de volgende code in het droge dit ding:
import java.lang.reflect .*;
public class veld1 {
eigen dubbele d;
public static definitieve int i = 37;
String s = "test";
public static void main (String args []) {
try {
Class = cls Class.forName ("veld1");
Gebied fieldlist [] = cls.getDeclaredFields ();
for (int i = 0; i fieldlist.length; i + +) {
Gebied Fld = fieldlist [i];
System.out.println ("naam =" + 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);
}
}
}
Dit voorbeeld en is zeer vergelijkbaar met het vorige voorbeeld.Bijvoorbeeld, maakt gebruik van een nieuw ding Modifier, het is ook een reflectie klasse, de leden van de modifier gebruikt om het veld te beschrijven, zoals "private int".Deze modifiers beschreven door het gehele getal zelf, en het gebruik Modifier.toString terug te keren naar de "officiële" omschrijving van de orde van de string (zoals "statische" in de "finale" voordien).Uitvoer van dit programma is:
naam = d
decl class = klasse veld1
type = dubbele
modifiers = particulier
-----
naam = i
decl class = klasse veld1
type = int
modifiers = public static definitieve
-----
naam = s
decl class = klasse veld1
type = klasse java.lang
modifiers =
De situatie en zoeken naar manieren om het veld te krijgen kan alleen worden bereikt wanneer de klas in de huidige staat van het veld informatie (getDeclaredFields), of u kunt de bovenliggende klasse definieert de velden (getfields).
6. Volgens de methode naam van de methode
Tekst hier, zonder uitzondering, alle voorbeelden en hoe informatie te verkrijgen over de klasse.We kunnen ook gebruik maken van reflectie naar een aantal andere dingen, zoals de wijze van uitvoering van het specificeren van een naam te doen.Het volgende voorbeeld illustreert het volgende:
import java.lang.reflect .*;
public class Methode2 {
public int toe te voegen (int a, int b) {
terug a + b;
}
public static void main (String args []) {
try {
Class = cls Class.forName ("Methode2");
Klasse partypes [] = new Klasse [2];
partypes [0] = Integer.TYPE;
partypes [1] = Integer.TYPE;
Methode meth = cls.getMethod ("toevoegen", partypes);
Methode2 methobj = new Methode2 ();
Object arglist [] = new Object [2];
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);
}
}
}
Als ergens in de uitvoering van een programma wanneer zij zich bewust van de noodzaak om een werkwijze uit te voeren, deze methode is de naam van het programma wordt uitgevoerd in de opgegeven (bijvoorbeeld JavaBean development omgeving zoiets zou doen), dan de bovenstaande procedurelaat zien hoe het te doen.
Het bovenstaande voorbeeld, getMethod gebruikt om twee integer parameters te vinden en een methode genaamd toe te voegen.Vind de methode en maken de bijbehorende methode object, het object bijvoorbeeld in het recht om het uit te voeren.De uitvoering van de methode, de noodzaak om een lijst van parameters, die hierboven in het voorbeeld is een geheel getal, respectievelijk 37 en 47 wikkels van twee Integer objecten.Methode voor de uitvoering is een integer terug hetzelfde object, waarvan de return waarde van 84 samenvat.
7. Om een nieuw object te maken
Voor de constructeur, hoef je niet zoals de implementatie van methoden, omdat het betekent dat de implementatie van een constructor maakt een nieuw object (om precies te zijn, het proces van het maken van een object met inbegrip van de toewijzing van geheugen en de bouw van een object).Ja, met de meest vergelijkbaar voorbeeld van het vorige voorbeeld als volgt:
import java.lang.reflect .*;
public class constructor2 {
openbare constructor2 () {
}
openbare constructor2 (int a, int b) {
System.out.println ("a =" + a + "b =" + b);
}
public static void main (String args []) {
try {
Class = cls Class.forName ("constructor2");
Klasse partypes [] = new Klasse [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);
}
}
}
Volgens de opgegeven parameter naar de juiste aannemer te vinden en uit te voeren om een nieuw object instantie te maken.Deze methode kan gebruikt worden tijdens runtime om dynamisch te maken van het object, in plaats van objecten te creëren tijdens het compileren, dat is zeer waardevol.
8. Wijzig het veld (veld) waarde
Er is ook een nuttige reflectie van het object is een wijziging van de waarde van gegevens veld.reflectie van een lopend programma om objecten te vinden met hun naam in het veld en veranderen, het volgende voorbeeld om dit punt te illustreren:
import java.lang.reflect .*;
public class veld2 {
openbare dubbele d;
public static void main (String args []) {
try {
Class = cls Class.forName ("veld2");
Gebied Fld = cls.getField ("d");
veld2 f2obj = new veld2 ();
System.out.println ("d =" + f2obj.d);
fld.setDouble (f2obj, 12.34);
System.out.println ("d =" + f2obj.d);
} Catch (Throwable e) {
System.err.println (e);
}
}
}
Dit voorbeeld wordt het veld de waarde veranderd door d 12,34.
9. Met behulp van arrays
Dit artikel beschrijft de reflectie van de laatste operatie is het creëren van een array van gebruik.Array in de Java-taal is een speciale klasse type, kan een array verwezen worden toegewezen Object referentie.Kijk naar het volgende voorbeeld om te zien hoe het werk van de array:
import java.lang.reflect .*;
public class array1 {
public static void main (String args []) {
try {
Class = cls Class.forName ("java.lang");
Object arr = Array.newInstance (CLS, 10);
Array.set (arr, 5, "dit is een test");
String s = (String) Array.get (arr, 5);
System.out.println (s);
} Catch (Throwable e) {
System.err.println (e);
}
}
}
Gevallen van 10 eenheden naar een String array van lengte, voor de eerste 5 posities van de string toegewezen aan een waarde te creëren, en ten slotte de string te krijgen van de array en print het uit.
De volgende code geeft een meer complex voorbeeld:
import java.lang.reflect .*;
public class matrix2 {
public static void main (String args []) {
int dimt [] = new int [] {5, 10, 15};
Object arr = Array.newInstance (Integer.TYPE, DIMS);
Object arrobj = Array.get (arr, 3);
Class = cls arrobj.getClass () GetComponentType ().;
System.out.println (CLS);
arrobj = Array.get (arrobj, 5);
Array.setInt (arrobj, 10, 37);
int arrcast [][][] = (int [][][]) arr;
System.out.println (arrcast [3] [5] [10]);
}
}
Voorbeeld maakt een 5 x 10 x 15 integer array, en in [3] [5] [10] een waarde toegekend van 37 elementen.Merk op dat multidimensionale arrays eigenlijk zijn arrays van arrays, bijvoorbeeld na de eerste Array.get, arrobj is een 10 x 15 array.Dan krijgt een van de elementen, dat wil zeggen, een array van lengte 15, en het gebruik Array.setInt voor de eerste 10 elementen van de opdracht.
Merk op dat wanneer u de array type dynamisch is, tijdens het compileren niet weet in zijn soort.