Refleksion er programmeringssproget Java én af de egenskaber, som gør det muligt at køre Java-programmer på deres egen kontrol, eller "self-undersøgelse", og kan tillægge direkte til det interne driftsprocedurer.For eksempel kan det blive en Java-klasse navnet på hvert enkelt medlem og skærm.
Java, kan i den praktiske anvendelse af denne evne skal anvendes, er ikke mange, men i andre programmeringssprog denne funktion findes simpelthen ikke.For eksempel, Pascal, C eller C + +, er der ingen måde at få funktionen definitionen i program-relaterede oplysninger.
JavaBean er en afspejling af den praktiske anvendelse, giver det mulighed visualiseringsværktøjer drift softwarekomponenter.Disse værktøjer er indlæst dynamisk gennem refleksion og få Java komponenter (klasser) af ejendommen.
1. Et simpelt eksempel
Overvej følgende enkle eksempel, lad os se, hvordan arbejdet refleksion.
importere java.lang.reflect .*;
public class DumpMethods {
public static void main (String args []) {
try {
Klasse C = Class.forName (args [0]);
Metode m [] = c.getDeclaredMethods ();
for (int i = 0; i m.length; i + +)
System.out.println (m [i] toString ().)
} Catch (Throwable e) {
System.out.println (e);
}
}
}
Opgørelsen er udført som følger:
java DumpMethods java.util.Stack
Det er den resulterende output er:
offentlige java.lang.Object java.util.Stack.push (java.lang.Object)
offentlige synkroniseret java.lang.Object java.util.Stack.pop ()
offentlige synkroniseret java.lang.Object java.util.Stack.peek ()
offentlige boolean java.util.Stack.empty ()
offentlige synkroniseret int java.util.Stack.search (java.lang.Object)
Dette er en liste navnet på hver metode java.util.Stack klasse og deres kvalifikationskamp og vende tilbage type.
Dette program bruger Class.forName til at indlæse den angivne klasse, så ring for at få denne getDeclaredMethods klasse definerer en metode liste.java.lang.reflect.Methods bruges til at beskrive en enkelt metode til en klasse af en klasse.
2. Startet Refleksion
For tænkningen af klassen, såsom metoden kan findes i java.lang.relfect pakken.Når du bruger disse klasser skal følge tre trin: Det første skridt er at få den klasse, du vil betjene java.lang.Class objekt.Kører i Java-programmet, med java.lang.Class klasse til at beskrive klasser og grænseflader.
Her er at opnå en klasse objekt metoder:
Klasse C = Class.forName ("java.lang.String");
Denne erklæring for at få en String klasse klasse objekt.Der er en anden måde, som de følgende erklæring:
Klasse C = int.class;
Eller
Klasse C = Integer.TYPE;
De modtager grundlæggende typer af klassen information.Besøg en af sidstnævnte metode er den grundlæggende type kolli (f.eks Integer) i præ-definerede feltet Type.
Det andet skridt er at kalde metoden, såsom getDeclaredMethods at indhente alle de metoder, der er defineret i klassen listen.
Når du har fået disse oplysninger, kan det tredje trin skal gennemføres - og bruge refleksion API til at manipulere oplysningerne, såsom den følgende kode:
Klasse C = Class.forName ("java.lang.String");
Metode m [] = c.getDeclaredMethods ();
System.out.println (m [0] toString ().)
Det vil udskrive som tekst String metoden i den første prototype.
I eksemplet nedenfor, tre trin til behandling af specifikke programmer til at bruge refleksion til at give eksempler.
Analog instanceof operatør
Efter få klassen oplysninger, normalt det næste skridt er at løse på Class genstand for en vis grundlæggende spørgsmål.For eksempel kan Class.isInstance metode anvendes til at simulere instanceof erhvervsdrivende:
klasse A {
}
public class instance1 {
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("A");
boolean b1 = cls.isInstance (ny heltal (37));
System.out.println (B1);
boolean b2 = cls.isInstance (ny A ());
System.out.println (B2);
} Catch (Throwable e) {
System.out.println (e);
}
}
}
I dette eksempel oprettes en klasse for klasse A genstande, og derefter kontrollere, om en genstand er en instans af A.Heltal (37) er ikke, men den nye A () er.
3. At finde klassens metoder
Find en klasse definerer, hvilke metoder, dette er en meget værdifuld anvendelse af meget grundlæggende refleksion.Følgende kode opnår denne brug:
importere java.lang.reflect .*;
public class Metode 1 {
private int f1 (Object p, int x) kaster NullPointerException {
hvis (p == null)
kaste nyt NullPointerException ();
tilbagevenden x;
}
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("Metode 1");
Metode methlist [] = cls.getDeclaredMethods ();
for (int i = 0; i methlist.length; i + +) {
Metode m = methlist [i];
System.out.println ("name =" + 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.out.println (e);
}
}
}
Dette program først få en beskrivelse af Metode 1 klasse, så ring getDeclaredMethods at få en række metode genstande, som er defineret i klassen beskrive hver af metoder, herunder offentlige metoder, beskyttede metoder, pakke private metoder og metoder.Hvis du bruger programmet til at erstatte getMethods getDeclaredMethods, kan du få alle de nedarvede metoder.
Metode til at opnå en liste over objekter, at parametrene for disse metoder viser type undtagelse typer og returværdi typer ikke svært.Disse typer er de grundlæggende type eller klasse type, kan beskrive den klasse af objekter af den givne rækkefølge.
Udgangen er som følger:
name = f1
decl class = klasse Metode 1
param # 0 klasse java.lang.Object
param # 1 int
exc # 0 klasse java.lang.NullPointerException
returtype = int
-----
name = vigtigste
decl class = klasse Metode 1
param # 0 klasse [Ljava.lang.String;
returtype = void
4. Få constructor oplysninger
Klassens konstruktør for anvendelsen af ovennævnte for brug af lignende metoder, såsom:
importere java.lang.reflect .*;
public class constructor1 {
offentlige constructor1 () {
}
beskyttet constructor1 (int i, dobbelt d) {
}
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("constructor1");
Constructor ctorlist [] = cls.getDeclaredConstructors ();
for (int i = 0; i ctorlist.length; i + +) {
Constructor ct = ctorlist [i];
System.out.println ("name =" + 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.out.println (e);
}
}
}
Denne sag kom ikke tilbage, hvilken type oplysninger, er det fordi leverandøren ikke vender tilbage type.
Resultatet af kører:
name = constructor1
decl class = klasse constructor1
-----
name = constructor1
decl class = klasse constructor1
param # 0 int
param # 1 dobbelt
5. For Klasse område (domæne)
Find en klasse definerer hvilke data felter er også muligt, følgende kode i tør denne ting:
importere java.lang.reflect .*;
public class field1 {
private dobbelt d;
public static endelig int i = 37;
String s = "test";
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("field1");
Felt fieldlist [] = cls.getDeclaredFields ();
for (int i = 0; i fieldlist.length; i + +) {
Felt 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 ();
System.out.println ("modifikatorer =" + Modifier.toString (mod));
System.out.println ("-----");
}
} Catch (Throwable e) {
System.out.println (e);
}
}
}
Dette eksempel og er meget lig det foregående eksempel.Eksempelvis bruger en ny ting Modifier, det er også en refleksion klasse, medlemmerne af modifikator bruges til at beskrive området, såsom "privat int".Disse modifiers beskrevet af heltal selv, og brug Modifier.toString at vende tilbage til den "officielle" beskrivelse af rækkefølgen af strengen (såsom "statisk" i "endelig" før).Produktionen af dette program er:
name = d
decl class = klasse field1
type = dobbelt
modifiers = privat
-----
name = Jeg
decl class = klasse field1
type = int
modifiers = public static endelige
-----
name = s
decl class = klasse field1
type = klasse java.lang.String
modifiers =
Situationen og finde måder at få feltet kan kun opnås, når den klasse, i den aktuelle situation i området oplysninger (getDeclaredFields), eller du kan få den forælder klasse definerer felterne (getfields).
6. Ifølge den metode, navnet på den metode,
Tekst her, uden undtagelse, at alle de eksempler, og hvordan indhente oplysninger om klassen.Vi kan også bruge refleksion til at gøre nogle andre ting, såsom gennemførelse metode at specificere et navn.Det følgende eksempel viser følgende:
importere java.lang.reflect .*;
public class metode2 {
public int add (int a, int b) {
tilbagevenden a + b;
}
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("metode2");
Klasse partypes [] = ny klasse [2];
partypes [0] = Integer.TYPE;
partypes [1] = Integer.TYPE;
Metode meth = cls.getMethod ("tilføj", partypes);
metode2 methobj = ny metode2 ();
Objekt arglist [] = new Object [2];
arglist [0] = new Integer (37);
arglist [1] = new Integer (47);
Objekt retobj = meth.invoke (methobj, arglist);
Heltal retval = (Integer) retobj;
System.out.println (retval.intValue ());
} Catch (Throwable e) {
System.out.println (e);
}
}
}
Hvis et eller andet sted i forbindelse med gennemførelsen af et program, før vi indser behovet for at udføre en metode, denne metode er navnet på det program, der kører i den angivne (for eksempel ville JavaBean udviklingsmiljø gøre sådan en ting), den ovenstående procedureviser, hvordan man gør det.
Ovenstående eksempel, getMethod bruges til at finde to heltal parametre og en metode kaldet tilføje.Find den metode og skabe den tilsvarende metode objekt, eksempelvis i retten til at udføre det.Gennemførelsen af metoden, at det er nødvendigt fremlægge en liste over parametre, som i eksemplet ovenfor er et heltal, henholdsvis 37 og 47 wraps af to heltal objekter.Udførelse metode er en heltal returnere det samme objekt, som indkapsler returværdien af 84.
7. Hvis du vil oprette et nyt objekt
For konstruktøren, behøver du ikke lide iværksættelse af metoder, fordi det betyder gennemførelsen af en constructor opretter et nyt objekt (at være helt nøjagtig, processen med at skabe et objekt herunder tildelingen af hukommelse og konstruere et objekt.)Så med de mest lignende eksempel i det foregående eksempel som følger:
importere java.lang.reflect .*;
public class constructor2 {
offentlige constructor2 () {
}
offentlige constructor2 (int a, int b) {
System.out.println ("a =" + a + "b =" + b);
}
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("constructor2");
Klasse partypes [] = ny klasse [2];
partypes [0] = Integer.TYPE;
partypes [1] = Integer.TYPE;
Constructor ct = cls.getConstructor (partypes);
Objekt arglist [] = new Object [2];
arglist [0] = new Integer (37);
arglist [1] = new Integer (47);
Objekt retobj = ct.newInstance (arglist);
} Catch (Throwable e) {
System.out.println (e);
}
}
}
Ifølge den angivne parameter skrive for at finde en passende konstruktør og udføre det til at oprette et nyt objekt instans.Denne metode kan bruges på kørselstidspunktet til dynamisk at oprette objektet, i stedet for at skabe objekter på kompilere tid, hvilket er meget værdifuldt.
8. Ændr felt (felt) værdi
Der er også en nyttig refleksion af objektet er at ændre værdien datafelt.refleksion fra en kørende program til at finde objekter ved navn i feltet og ændre det, det følgende eksempel for at illustrere dette punkt:
importere java.lang.reflect .*;
public class field2 {
offentlige dobbelt d;
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("field2");
Felt Fld = cls.getField ("d");
field2 f2obj = ny field2 ();
System.out.println ("d =" + f2obj.d);
fld.setDouble (f2obj, 12,34);
System.out.println ("d =" + f2obj.d);
} Catch (Throwable e) {
System.out.println (e);
}
}
}
Dette eksempel, er feltets værdi ændres ved d 12,34.
9. Brug af arrays
Denne artikel beskriver afspejling af den endelige operation er at skabe en bred vifte af brug.Array i Java-sproget er en særlig klasse type, kan en tabelreference tildeles Object reference.Kig på følgende eksempel at se, hvordan arbejdet i array:
importere java.lang.reflect .*;
public class vektor1 {
public static void main (String args []) {
try {
Klasse CLS = Class.forName ("java.lang.String");
Objekt arr = Array.newInstance (CLS, 10);
Array.set (arr., 5, "dette er en test");
String s = (String) Array.get (arr., 5);
System.out.println (s);
} Catch (Throwable e) {
System.out.println (e);
}
}
}
Tilfælde af 10 enheder for at skabe en String array af længde, for de første 5 positioner strengen tildeles en værdi, og endelig får snoren fra rækken, og printe det ud.
Følgende kode giver en mere kompleks eksempel:
importere java.lang.reflect .*;
public class matrix2 {
public static void main (String args []) {
int dæmpes [] = new int [] {5, 10, 15};
Objekt arr = Array.newInstance (Integer.TYPE, DIMS);
Objekt arrobj = Array.get (arr., 3);
Klasse 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]);
}
}
Eksempel oprettes en 5 x 10 x 15 heltal array, og i [3] [5] [10] tildelt en værdi af 37 elementer.Bemærk, at multidimensional arrays er faktisk arrays af arrays, for eksempel efter det første Array.get er arrobj en 10 x 15 array.Så få et af de elementer, dvs en række af længde 15, og bruge Array.setInt for sine første 10 elementer af opgaven.
Bemærk, at når du opretter et array type er dynamisk, påkompileringstidspunktet ikke kender sin type.