Java Reflection Application Detailed introduction _java programming

Source: Internet
Author: User
Tags abstract array length modifier modifiers null null reflection
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


Copy Code code as follows:

package reflect;
/**
* Get the complete package name and class name from an object
* */
Class demo{
Other codes ...
}

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


Copy Code code as follows:

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


Copy Code code as follows:



package reflect;


Class person{





Public String GetName () {


return name;


}


public void SetName (String name) {


THIS.name = name;


}


public int getage () {


return age;


}


public void Setage (int age) {


This.age = 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&lt;?&gt; Demo=null;


try{


Demo=class.forname ("Reflect.person");


}catch (Exception e) {


E.printstacktrace ();


}


Person Per=null;


try {


per= (person) demo.newinstance ();


catch (Instantiationexception e) {


TODO auto-generated Catch block


E.printstacktrace ();


catch (Illegalaccessexception e) {


TODO auto-generated Catch block


E.printstacktrace ();


}


Per.setname ("Rollen");


Per.setage (20);


System.out.println (per);


}


}





"Run Results":


[Rollen 20]


But note that when we cancel the default parameterless constructor in person, such as defining a constructor that has only one parameter, an error occurs:


For example, I define a constructor:


Copy Code code as follows:



Public person (String name, int age) {


This.age=age;


This.name=name;


}


Then continue running the above program, and it will appear:


Java.lang.InstantiationException:Reflect.Person


At Java.lang.Class.newInstance0 (class.java:340)


At Java.lang.Class.newInstance (class.java:308)


At Reflect.hello.main (hello.java:39)


Exception in thread "main" java.lang.NullPointerException


At Reflect.hello.main (hello.java:47)


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)


[Code]


package reflect;


Import Java.lang.reflect.Constructor;





Class person{





Public person () {





}


Public person (String name) {


This.name=name;


}


public person (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&lt;?&gt; 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&lt;?&gt; 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:


[Code]


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, the");


}


@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&lt;?&gt; Demo=null;


try{


Demo=class.forname ("Reflect.person");


}catch (Exception e) {


E.printstacktrace ();


}


Save all the interfaces


Class&lt;?&gt; intes[]=demo.getinterfaces ();


for (int i = 0; i &lt; 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


Copy Code code as follows:

Class hello{
public static void Main (string[] args) {
Class<?> Demo=null;
try{
Demo=class.forname ("Reflect.person");
}catch (Exception e) {
E.printstacktrace ();
}
Get 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:


Copy Code code as follows:

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 ("Construction Method:" +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.


Copy Code code as follows:

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:


Copy Code code as follows:



Class hello{


public static void Main (string[] args) {


Class&lt;?&gt; Demo=null;


try{


Demo=class.forname ("Reflect.person");


}catch (Exception e) {


E.printstacktrace ();


}


Method Method[]=demo.getmethods ();


for (int i=0;i&lt;method.length;++i) {


Class&lt;?&gt; Returntype=method[i].getreturntype ();


Class&lt;?&gt; 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&lt;para.length;++j) {


System.out.print (Para[j].getname () + "" + "arg" +j);


if (j&lt;para.length-1) {


System.out.print (",");


}


}


Class&lt;?&gt; exce[]=method[i].getexceptiontypes ();


if (exce.length&gt;0) {


System.out.print (") throws");


for (int k=0;k&lt;exce.length;++k) {


System.out.print (Exce[k].getname () + "");


if (k&lt;exce.length-1) {


System.out.print (",");


}


}


}else{


System.out.print (")");


}


System.out.println ();


}


}


}





"Run Results":


Public java.lang.String Getsex ()


public void Setsex (java.lang.String arg0)


public void Saychina ()


public void SayHello (java.lang.String arg0,int arg1)


Public final native void wait (long arg0) throws Java.lang.InterruptedException


Public final void Wait () throws Java.lang.InterruptedException


Public final void Wait (long arg0,int arg1) throws Java.lang.InterruptedException


public boolean equals (Java.lang.Object arg0)


Public java.lang.String toString ()


public native int Hashcode ()


Public final native Java.lang.Class GetClass ()


Public final native void Notify ()


Public final native void Notifyall ()


"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.


Copy Code code as follows:



Class Hello {


public static void Main (string[] args) {


Class&lt;?&gt; demo = null;


try {


Demo = Class.forName ("Reflect.person");


catch (Exception e) {


E.printstacktrace ();


}


System.out.println ("=============== This class of attributes ========================");


Get all the properties of this class


field[] field = Demo.getdeclaredfields ();


for (int i = 0; i &lt; field.length; i++) {


Permission modifiers


int mo = Field[i].getmodifiers ();


String priv = modifier.tostring (MO);


Property type


class&lt;?&gt; 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 interface of the implementation or the properties of the parent class


field[] filed1 = Demo.getfields ();


for (int j = 0; J &lt; Filed1.length; J + +) {


Permission modifiers


int mo = Filed1[j].getmodifiers ();


String priv = modifier.tostring (MO);


Property type


class&lt;?&gt; 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:


Copy Code code as follows:

Class Hello {
public static void Main (string[] args) {
Class<?> demo = null;
try {
Demo = Class.forName ("Reflect.person");
catch (Exception e) {
E.printstacktrace ();
}
try{
Calling the Saychina method in the person class
Method Method=demo.getmethod ("Saychina");
Method.invoke (Demo.newinstance ());
SayHello method to invoke person
Method=demo.getmethod ("SayHello", String.class,int.class);
Method.invoke (Demo.newinstance (), "Rollen", 20);

}catch (Exception e) {
E.printstacktrace ();
}
}
}



"Run Results":


Hello,


Rollen 20


"Case" calls the set and get methods of other classes


Copy Code code as follows:



Class Hello {


public static void Main (string[] args) {


Class&lt;?&gt; 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


* Object of operation


* @param att


* Properties of the operation


* */


public static void Getter (Object obj, String att) {


try {


method is = Obj.getclass (). GetMethod ("get" + att);


System.out.println (Method.invoke (obj));


catch (Exception e) {


E.printstacktrace ();


}


}





/**


* @param obj


* Object of operation


* @param att


* Properties of the operation


* @param value


* Set the value


* @param type


* Properties of the parameter


* */


public static void Setter (Object obj, String att, object value,


Class&lt;?&gt; 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


Copy code code as follows:

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:
[Code]
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, 100);
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


Copy Code code as follows:



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&lt;?&gt;arr=obj.getclass (). Getcomponenttype ();


Object newarr=array.newinstance (arr, Len);


int co=array.getlength (obj);


System.arraycopy (obj, 0, NEWARR, 0, CO);


return NEWARR;


}


/**


* Print


* */


public static void print (Object obj) {


Class&lt;?&gt;c=obj.getclass ();


if (!c.isarray ()) {


Return


}


SYSTEM.OUT.PRINTLN ("Array length is:" +array.getlength (obj));


for (int i = 0; i &lt; 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:


Copy Code code as follows:



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.


[Code]


package reflect;


Import java.lang.reflect.*;





Defining Project Interfaces


Interface Subject {


public string Say (string name, int age);


}





Define Real Project


Class Realsubject implements Subject {


@Override


public string Say (string name, int age) {


Return 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:


Http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144851.html


Copy Code code as follows:

/**
* @author Rollen-holt design pattern of the factory model
*/

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 Factory class


That means we'll just have to modify the factory class when we add other instances.


Copy Code code as follows:

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:


Copy Code code as follows:

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:


? 1


2 Apple=reflect.apple


Orange=reflect.orange


Then write the main class code:





Copy Code code as follows:

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");
}
}



Action Properties File Class


Copy Code code as follows:



Class init{


public static Properties Getpro () throws FileNotFoundException, ioexception{


Properties 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=init.getpro ();


Fruit f=factory.getinstance (Pro.getproperty ("Apple"));


if (f!=null) {


F.eat ();


}


}


}





"Run Results": Apple
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.