This article is still using a small example to illustrate, because I always feel that the case driven is the best, or only to see the theory, read also do not understand, but suggest that after reading the article, in retrospect to look at the theory, will have a better understanding.
Start the text below.
Case 1 Gets the complete package name and class name from an object
package reflect;
/**
* Obtains the complete package name and class name * * * * * * * * * * * * * * * * */class
demo{
//other codes
through an object Class hello{public
static void Main (string[] args) {
demo demo=new demo ();
System.out.println (Demo.getclass (). GetName ());
}
"Run Results": Reflect.demo
Add a sentence: All class objects are actually instances of class.
Case 2 Instantiating the Class class object
package reflect;
Class demo{
//other codes ...
}
Class hello{public
static void Main (string[] args) {
class<?> demo1=null;
Class<?> Demo2=null;
Class<?> Demo3=null;
try{
//generally try to use this form
demo1=class.forname ("Reflect.demo");
} catch (Exception e) {
e.printstacktrace ();
}
Demo2=new Demo (). GetClass ();
Demo3=demo.class;
System.out.println ("Class name " +demo1.getname ());
System.out.println ("Class name " +demo2.getname ());
System.out.println (class name +demo3.getname ());
}
"Run Results":
Class name Reflect.demo
Class name Reflect.demo
Class name Reflect.demo
Case 3 instantiating objects of other classes by class
Instantiating an object through an parameterless construct
Public person (String name, int age) {
this.age=age;
This.name=name;
}
Then continue running the above program, and it will appear:
So when you write an object that uses class to instantiate another class, be sure to define the parameterless constructor yourself.
"Case" calls constructors in other classes through class (or you can create objects of other classes through class in this way)
package reflect;
Import Java.lang.reflect.Constructor;
Class person{Public person () {} public person (String name) {this.name=name;
(int age) {this.age=age;
Public person (String name, int age) {this.age=age;
This.name=name;
Public String GetName () {return name;
public int getage () {return age;
@Override public String toString () {return "[" +this.name+ "" +this.age+ "]";
private String name;
private int age;
Class hello{public static void Main (string[] args) {class<?> demo=null;
try{demo=class.forname ("Reflect.person");
}catch (Exception e) {e.printstacktrace ();
Person Per1=null;
Person Per2=null;
Person Per3=null;
Person Per4=null;
Get all the constructors constructor<?> cons[]=demo.getconstructors ();
try{per1= (person) cons[0].newinstance (); per2= (person) cons[1].neWinstance ("Rollen");
per3= (person) cons[2].newinstance (20);
per4= (person) cons[3].newinstance ("Rollen", 20);
}catch (Exception e) {e.printstacktrace ();
} System.out.println (Per1);
System.out.println (PER2);
System.out.println (PER3);
System.out.println (PER4); }
}
"Run Results":
[NULL 0]
[Rollen 0]
[NULL 20]
[Rollen 20]
Case
Returns the interface implemented by a class:
package reflect;
Interface china{public static final String name= "Rollen";
public static int age=20;
public void Saychina ();
public void SayHello (String name, int age);
Class person implements china{public person () {} public person (String sex) {this.sex=sex;
Public String Getsex () {return sex;
} public void Setsex (String sex) {this.sex = sex;
@Override public void Saychina () {System.out.println ("Hello,");
@Override public void SayHello (String name, int age) {System.out.println (name+ "" +age);
Private String sex;
Class hello{public static void Main (string[] args) {class<?> demo=null;
try{demo=class.forname ("Reflect.person");
}catch (Exception e) {e.printstacktrace ();
//Save all the Interfaces class<?> intes[]=demo.getinterfaces (); for (int i = 0; i < intes.length i++) {SYSTEM.OUT.PRINTLN ("implemented interface" +intes[I].getname ()); }
}
}
"Run Results":
Implementation of the interface Reflect.china
(Note that the following examples will use the person class for this example, so to save space, the code part of the person is no longer pasted, just the code for the main class hello)
"Case": getting the parent class in another class
Class hello{public
static void Main (string[] args) {
class<?> demo=null;
try{
demo=class.forname ("Reflect.person");
} catch (Exception e) {
e.printstacktrace ();
}
Get the parent class
class<?> Temp=demo.getsuperclass ();
System.out.println ("Inherited parent class is: " +temp.getname ());
}
"Run Results"
The inherited parent class is: Java.lang.Object
"Case": get all constructors in other classes
This example needs to add the import java.lang.reflect.* at the beginning of the program;
The main class is then written as:
Class hello{public
static void Main (string[] args) {
class<?> demo=null;
try{
demo=class.forname ("Reflect.person");
} catch (Exception e) {
e.printstacktrace ();
}
Constructor<?>cons[]=demo.getconstructors ();
for (int i = 0; i < cons.length i++) {
System.out.println ("constructor:" +cons[i]);}}
"Run Results":
Construction method: Public Reflect.person ()
Construction method: Public Reflect.person (java.lang.String)
But a careful reader will find that the constructor above does not have a modifier such as public or private.
Here's an example where we'll get the modifiers.
Class hello{public
static void Main (string[] args) {
class<?> demo=null;
try{
demo=class.forname ("Reflect.person");
} catch (Exception e) {
e.printstacktrace ();
}
Constructor<?>cons[]=demo.getconstructors ();
for (int i = 0; i < cons.length i++) {
class<?> p[]=cons[i].getparametertypes ();
System.out.print ("Construction Method:");
int mo=cons[i].getmodifiers ();
System.out.print (modifier.tostring (MO) + "");
System.out.print (Cons[i].getname ());
System.out.print ("(");
for (int j=0;j<p.length;++j) {
System.out.print (p[j].getname () + "arg" +i);
if (j<p.length-1) {
System.out.print (",");
}
}
System.out.println (") {}");}}
"Run Results":
Construct method: Public Reflect.person () {}
Construct method: Public Reflect.person (java.lang.String arg1) {}
Sometimes a method may have an exception, hehe. Look at the following:
Class hello{public static void Main (string[] args) {class<?> demo=null;
try{demo=class.forname ("Reflect.person");
}catch (Exception e) {e.printstacktrace ();
Method Method[]=demo.getmethods ();
for (int i=0;i<method.length;++i) {class<?> returntype=method[i].getreturntype ();
Class<?> para[]=method[i].getparametertypes ();
int temp=method[i].getmodifiers ();
System.out.print (modifier.tostring (temp) + "");
System.out.print (Returntype.getname () + "");
System.out.print (Method[i].getname () + "");
System.out.print ("(");
for (int j=0;j<para.length;++j) {System.out.print (Para[j].getname () + "" + "arg" +j);
if (j<para.length-1) {System.out.print (",");
} class<?> exce[]=method[i].getexceptiontypes ();
if (exce.length>0) {System.out.print (") throws");
for (int k=0;k<exce.length;++k) { System.out.print (Exce[k].getname () + "");
if (k<exce.length-1) {System.out.print (",");
}}else{System.out.print (")");
} System.out.println (); }
}
}
"Case" next let's get all the properties of the other classes, and finally I'm going to say these things together, which is to get all the frames of a class through class.
Class Hello {public static void main (string[] args) {class<?> demo = null;
try {demo = Class.forName ("Reflect.person");
catch (Exception e) {e.printstacktrace ();
} System.out.println ("=============== This class attribute ========================");
Get all the properties of this class field[] Field = Demo.getdeclaredfields ();
for (int i = 0; i < field.length i++) {//rights modifier int mo = Field[i].getmodifiers ();
String priv = modifier.tostring (MO);
Property type Class<?> type = Field[i].gettype ();
System.out.println (Priv + "" + type.getname () + "" + field[i].getname () + ";");}
SYSTEM.OUT.PRINTLN ("=============== implemented interface or attribute ======================== of the parent class");
Gets the implemented interface or the parent class's properties field[] filed1 = Demo.getfields ();
for (int j = 0; J < Filed1.length; J +) {//permission modifier int mo = Filed1[j].getmodifiers ();
String priv = modifier.tostring (MO); Property Type CLASS<?>
Type = Filed1[j].gettype (); System.out.println (Priv + "" + type.getname () + "" + filed1[j].getname () + ";");}}
"Run Results":
=============== This class property ========================
Private java.lang.String sex;
=============== implements the interface or the properties of the parent class ========================
public static final java.lang.String name;
public static final int age;
A case can actually invoke a method in another class by reflection:
Class Hello {public
static void Main (string[] args) {
class<?> demo = null;
try {
demo = Class.forName ("Reflect.person");
} catch (Exception e) {
e.printstacktrace ();
}
try{
//Invoke the Saychina method in the person class to
Method=demo.getmethod ("Saychina");
Method.invoke (Demo.newinstance ());
Invoke the SayHello method of person
method=demo.getmethod ("SayHello", string.class,int.class);
Method.invoke (Demo.newinstance (), "Rollen");
} catch (Exception e) {
e.printstacktrace ();}}}
"Run Results":
Hello,
Rollen 20
"Case" calls the set and get methods of other classes
Class Hello {public static void main (string[] args) {class<?> demo = null;
Object Obj=null;
try {demo = Class.forName ("Reflect.person");
catch (Exception e) {e.printstacktrace ();
} try{obj=demo.newinstance ();
}catch (Exception e) {e.printstacktrace ();
Setter (obj, "Sex", "male", string.class);
Getter (obj, "Sex"); /** * @param obj * Operation object * @param att * */public static void Getter
obj, String att) {try {method method = Obj.getclass (). GetMethod (' get ' + att);
System.out.println (Method.invoke (obj));
catch (Exception e) {e.printstacktrace ();
/** * @param obj * Operation object * @param att * Operation property * @param value * Set * @param type * Parameter's properties */public static void Setter (Object obj, String att, object value, Class< ;? > type) {try {
Method method = Obj.getclass (). GetMethod ("set" + ATT, type);
Method.invoke (obj, value);
catch (Exception e) {e.printstacktrace (); }}//End Class
"Run Results":
Man
"Case" Action properties by reflection
Class Hello {public
static void Main (string[] args) throws Exception {
class<?> demo = null;
Object obj = null;
Demo = Class.forName ("Reflect.person");
obj = Demo.newinstance ();
Field field = Demo.getdeclaredfield ("Sex");
Field.setaccessible (true);
Field.set (obj, "male");
System.out.println (Field.get (obj));
}
End Class
The case gets and modifies the information of the array by reflection:
Import java.lang.reflect.*;
Class hello{public
static void Main (string[] args) {
int[] temp={1,2,3,4,5};
Class<?>demo=temp.getclass (). Getcomponenttype ();
SYSTEM.OUT.PRINTLN ("Array type:" +demo.getname ());
SYSTEM.OUT.PRINTLN ("Array Length" +array.getlength (temp));
System.out.println ("The first element of the array:" +array.get (temp, 0));
Array.set (temp, 0, MB);
SYSTEM.OUT.PRINTLN (the first element of the array after modification is: +array.get (temp, 0));
}
"Run Results":
Array type: INT
Array length 5
The first element of the array: 1
After modification the first element of the array is: 100
"Case" modifies the size of an array by reflection
class hello{public static void Main (string[] args) {int[] temp={1,2,3,4,5,6,7,
8,9};
Int[] newtemp= (int[]) arrayinc (temp,15);
Print (newtemp);
System.out.println ("=====================");
String[] atr={"A", "B", "C"};
String[] str1= (string[]) arrayinc (atr,8);
Print (STR1); /** * Modify Array size */public static object Arrayinc (Object obj,int len) {Class<?>arr=obj.getclas
S (). Getcomponenttype ();
Object newarr=array.newinstance (arr, Len);
int co=array.getlength (obj);
System.arraycopy (obj, 0, NEWARR, 0, CO);
return NEWARR;
/** * */public static void print (Object obj) {class<?>c=obj.getclass ();
if (!c.isarray ()) {return;
SYSTEM.OUT.PRINTLN ("Array Length:" +array.getlength (obj));
for (int i = 0; i < array.getlength (obj); i++) {System.out.print (Array.get (obj, i) + ""); }
}
}
"Run Results":
The length of the array is: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0-0 =====================
The length of the array is: 8
A b c null null NULL
Dynamic Proxy
The case first looks at how to get the ClassLoader:
Class test{
}
class hello{public
static void Main (string[] args) {
Test t=new test ();
SYSTEM.OUT.PRINTLN (class loader +t.getclass (). getClassLoader (). GetClass (). GetName ());
}
"Program Output":
Class Loader Sun.misc.launcher$appclassloader
In fact, there are three kinds of class loaders in Java.
1) Bootstrap ClassLoader This loader is written in C + +, common development is very rare.
2) Extension ClassLoader is used to load extended classes, typically corresponding to classes in the Jre\lib\ext directory
3) Appclassloader load Classpath specified class, is the most commonly used loader. It is also the default loader in Java.
If you want to complete a dynamic proxy, you first need to define a subclass of the Invocationhandler interface, which completes the agent's actions.
package reflect;
Import java.lang.reflect.*;
Defines the project interface interface Subject {public string say (string name, int age); }//define Real Project class Realsubject implements Subject {@Override public string say (string name, int age) {Retur
N name + "" + age;
Class Myinvocationhandler implements Invocationhandler {private Object obj = null;
public object bind (Object obj) {this.obj = obj;
Return Proxy.newproxyinstance (Obj.getclass (). getClassLoader (), obj. GetClass (). Getinterfaces (), this); @Override public Object Invoke (object proxy, Method method, object[] args) throws Throwable {Object
temp = Method.invoke (this.obj, args);
return temp; } class Hello {public static void main (string[] args) {Myinvocationhandler demo = new Myinvocationhandler (
);
Subject sub = (Subject) demo.bind (New Realsubject ());
String info = Sub.say ("Rollen", 20);
SYSTEM.OUT.PRINTLN (info); }
}
"Run Results":
Rollen 20
The life cycle of a class
After a class has been compiled, the next step is to start using the class, and if you want to use a class, you must not leave the JVM. In program execution the JVM completes the 3 steps by loading, linking, and initializing.
The loading of the class is done through the ClassLoader, which loads the binaries of the. class file into the method area of the JVM and creates a Java.lang.Class object that describes the class in the heap area. Used to encapsulate data. But the same class will only be loaded by the class loader before
A link is to assemble binary data into a state that can be run.
Links are divided into checksums, preparation, parsing these 3 stages
Checksums are generally used to confirm that this binary is appropriate for the current JVM (version).
Preparation is the allocation of memory space for static members. and set the default value
Parsing refers to the process of converting code in a constant pool as a direct reference until all symbolic references can be used by the running program (establish a complete correspondence)
When finished, the type is initialized, and the object of the class is used normally until an object is no longer in use and is garbage collected. Free space.
is unloaded when no reference is directed to the class object, ending the lifecycle of the class
Apply reflection to Factory mode
Let's take a look at the factory model if you don't have to reflect it:
/**
* @author rollen-holt design mode of the Factory mode * *
interface fruit{public
abstract void Eat ();
Class Apple implements fruit{public
void Eat () {
System.out.println ("Apple");
}
Class Orange implements fruit{public
void Eat () {
System.out.println ("Orange");
}
Construct the factory class
//That is, if we need to modify the factory class only when we add other instances,
class factory{public
static Fruit getinstance (String Fruitname) {
fruit f=null;
if ("Apple". Equals (Fruitname)) {
f=new apple ();
}
if ("Orange". Equals (Fruitname)) {
f=new orange ();
}
return f;
}
}
Class hello{public
static void Main (string[] a) {
fruit f=factory.getinstance ("Orange");
F.eat ();
}
In this way, when we add a subclass, we need to modify the factory class. If we add too many subclasses, there will be a lot of changes.
Now let's take a look at the reflection mechanism:
package reflect;
Interface fruit{public
abstract void Eat ();
}
Class Apple implements fruit{public
void Eat () {
System.out.println ("Apple");
}
Class Orange implements fruit{public
void Eat () {
System.out.println ("Orange");
}
Class factory{public
static Fruit getinstance (String ClassName) {
fruit f=null;
try{
f= (fruit) class.forname (ClassName). newinstance ();
catch (Exception e) {
e.printstacktrace ();
}
return f;
}
}
Class hello{public
static void Main (string[] a) {
fruit f=factory.getinstance ("reflect.apple");
if (f!=null) {
f.eat ();}}}
Now even if we add as many subclasses as we want, the factory class doesn't need to be modified.
The love above? Although you can get an instance of an interface through reflection, you need to pass in the full package and class name. And the user has no way of knowing how many subclasses a single interface can use, so we configure the required subclasses in the form of a property file.
Let's take a look at: The factory model combining attribute files
First, create a fruit.properties resource file,
Content is:
Apple=reflect.apple
Orange=reflect.orange
Then write the main class code:
package reflect;
Import java.io.*;
Import java.util.*;
Interface fruit{public abstract void eat ();
Class Apple implements fruit{public void Eat () {System.out.println ("Apple");
Class Orange implements fruit{public void Eat () {System.out.println ("Orange"); }//Operations Properties File class class init{public static Properties Getpro () throws FileNotFoundException, ioexception{Proper
Ties Pro=new Properties ();
File F=new file ("Fruit.properties");
if (f.exists ()) {Pro.load (new FileInputStream (f));
}else{pro.setproperty ("Apple", "reflect.apple");
Pro.setproperty ("Orange", "Reflect.orange");
Pro.store (new FileOutputStream (f), "FRUIT CLASS");
return pro;
Class factory{public static Fruit getinstance (String ClassName) {fruit f=null;
try{f= (Fruit) class.forname (ClassName). newinstance ();
}catch (Exception e) {e.printstacktrace ();
} return F;Class hello{public static void Main (string[] a) throws FileNotFoundException, ioexception{Properties pro=i
Nit.getpro ();
Fruit f=factory.getinstance (Pro.getproperty ("Apple"));
if (f!=null) {f.eat (); }
}
}
The above Java reflection in-depth analysis (recommended) is a small series to share all the content, hope to give you a reference, but also hope that we support the cloud-dwelling community.