Foreword # #
A few days ago, I was studying a Router (routing mode) Demo, which was written very well. I happened to find reflection used in it. I thought I should take it out and write something about it.
So it was decided that the ultimate goal of this series was to customize the awesome database framework: to create a core Demo that mimicked the latest popular database framework patterns with annotations and reflections (just look at the core ideas, with minimal concern for code robustness).
When I first got to know Java, I was very disgusted with reflection. A lot of code I didn’t know about destroyed the original design structure. After a long time of code development, I found it was actually very cute.
One hundred people have one hundred ideas, so others design may be something to do with your design ideas are not the same, all had to use reflection to reach own purpose, a lot of people say that reflection is actually a very consume resources, no use unless it is, after this we can actually test.
On the Internet to find a lot of information, write are great, feel I write things certainly no one else to write good, I directly find a I think the most concise and clear reprinted.
# # text
The original blog http://www.cnblogs.com/lzq198754/p/5780331.html
What is the reflex mechanism
Reflection mechanism is in the running state, for any class, can know all the attributes and methods of the class; For any object, you can call any of its methods and properties; This ability to dynamically retrieve information and invoke methods on objects is called the Reflection mechanism of the Java language. 2 What can reflex mechanisms do
The reflection mechanism provides the following functions:
Determine the class of any object at run time; Construct an object of any class at runtime; Determine which member variables and methods any class has at run time. Call a method of any object at runtime; Generate dynamic proxies.Copy the code
The reflection API gets the full package name and class name from an object
package net.xsoftlab.baike;
public class TestReflect {
public static void main(String[] args) throws Exception {
TestReflect testReflect = new TestReflect();
System.out.println(testReflect.getClass().getName()); / / the result net. Xsoftlab. Baike. TestReflect}}Copy the code
Instantiate the Class object
package net.xsoftlab.baike; public class TestReflect { public static void main(String[] args) throws Exception { Class<? > class1 = null; Class<? > class2 = null; Class<? > class3 = null; Class1 = class.forname ("net.xsoftlab.baike.TestReflect");
class2 = new TestReflect().getClass();
class3 = TestReflect.class;
System.out.println("Class Name" + class1.getName());
System.out.println("Class Name" + class2.getName());
System.out.println("Class Name"+ class3.getName()); }}Copy the code
Gets the interface between an object’s parent class and its implementation
package net.xsoftlab.baike; import java.io.Serializable; public class TestReflect implements Serializable { private static final long serialVersionUID = -2862585049955236662L; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect"); // Get the parent Class<? > parentClass = clazz.getSuperclass(); System.out.println("The parent of clazz is:"+ parentClass.getName()); // Clazz's parent Class is java.lang.Object. > intes[] = clazz.getInterfaces(); System.out.println(Clazz implements the following interfaces:);
for (int i = 0; i < intes.length; i++) {
System.out.println((i + 1) + ":"+ intes[i].getName()); // 1: java.io.Serializable}}Copy the code
Get all constructors in a class – see the example below for instantiating an object of a class through reflection
package net.xsoftlab.baike; import java.lang.reflect.Constructor; public class TestReflect { public static void main(String[] args) throws Exception { Class<? > class1 = null; class1 = Class.forName("net.xsoftlab.baike.User"); // The first method, instantiating the default constructor, callssetAssignment User User = (User) class.newinstance (); user.setAge(20); user.setName("Rollen"); System.out.println(user); User [age=20, name=Rollen] // The second way to get all constructors is to assign Constructor<? > cons[] = class1.getConstructors(); // View the parameters required by each constructorfor(int i = 0; i < cons.length; i++) { Class<? > clazzs[] = cons[i].getParameterTypes(); System.out.print("cons[" + i + "] (");
for (int j = 0; j < clazzs.length; j++) {
if (j == clazzs.length - 1)
System.out.print(clazzs[j].getName());
else
System.out.print(clazzs[j].getName() + ",");
}
System.out.println(")"); } // result // cons[0] (java.lang.string) // cons[1] (int, java.lang.string) // cons[2] () user = (user) cons[0].newinstance ()"Rollen"); System.out.println(user); // Result User [age=0, name=Rollen] User = (User) cons[1]. NewInstance (20,"Rollen"); System.out.println(user); User [age=20, name=Rollen]}} class User {private int age; private String name; publicUser() {
super();
}
public User(String name) {
super();
this.name = name;
}
public User(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]"; }}Copy the code
Gets all attributes of a class
package net.xsoftlab.baike; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class TestReflect implements Serializable { private static final long serialVersionUID = -2862585049955236662L; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect");
System.out.println("=============== Attributes of this class ==============="); Field[] Field = clazz.getDeclaredFields();for(int i = 0; i < field.length; I ++) {int mo = field[I].getMODIfiers (); String priv = Modifier.toString(mo); // Attribute type Class<? >type = field[i].getType();
System.out.println(priv + "" + type.getName() + "" + field[i].getName() + ";");
}
System.out.println("========== implemented interface or superclass property =========="); Field[] filed1 = clazz.getFields();for(int j = 0; j < filed1.length; J ++) {// permission modifier int mo = filed1[j]. String priv = Modifier.toString(mo); // Attribute type Class<? >type = filed1[j].getType();
System.out.println(priv + "" + type.getName() + "" + filed1[j].getName() + ";"); }}}Copy the code
Gets all the methods of a class
package net.xsoftlab.baike; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TestReflect implements Serializable { private static final long serialVersionUID = -2862585049955236662L; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect");
Method method[] = clazz.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(); }}}Copy the code
Call a method of a class through reflection
package net.xsoftlab.baike; import java.lang.reflect.Method; public class TestReflect { public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect"); Method reflect1 = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); // Call TestReflect reflect2 method method = clazz.getMethod("reflect2", int.class, String.class);
method.invoke(clazz.newInstance(), 20, "Zhang"); 2. // age -> 20. name -> j3} public voidreflect1() {
System.out.println("Java reflection mechanism - calling a class method 1.");
}
public void reflect2(int age, String name) {
System.out.println("Java reflection mechanism - calling a class method 2.");
System.out.println("age -> " + age + ". name -> "+ name); }}Copy the code
Manipulate attributes of a class through reflection
package net.xsoftlab.baike; import java.lang.reflect.Field; public class TestReflect { private String proprety = null; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect"); Object obj = clazz.newInstance(); Clazz.getdeclaredfield (clazz.getDeclaredField);"proprety");
field.setAccessible(true);
field.set(obj, "Java Reflection mechanism"); System.out.println(field.get(obj)); }}Copy the code
Dynamic proxy of reflection mechanism
// Get the classloader method TestReflecttestReflect = new TestReflect();
System.out.println("Class loader" + testReflect.getClass().getClassLoader().getClass().getName()); package net.xsoftlab.baike; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; Interface Subject {public String say(String name, int age); Public String say(String name, int age) {RealSubject implements Subject {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);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object temp = method.invoke(this.obj, args);
returntemp; }} /** * There are three types of classloaders in Java. * * 1) Bootstrap ClassLoader this loader is written in c++, which is rare in general development. * * 2) Extension ClassLoader is used to load Extension classes, usually corresponding to the jrelibext directory * * 3) AppClassLoader is used to load classes specified by classpath, which is the most common loader. It is also the default loader in Java. * * If you want to complete the dynamic proxy, you first need to define a subclass of the InvocationHandler interface to complete the proxy operation. * * @author xsoftlab.net * */ public class TestReflect { public static void main(String[] args) throws Exception { MyInvocationHandler demo = new MyInvocationHandler(); Subject sub = (Subject) demo.bind(new RealSubject()); String info = sub.say("Rollen", 20); System.out.println(info); }}Copy the code
4 Application example of reflection Stores an object of type String in an ArrayList whose generic type is Integer.
package net.xsoftlab.baike;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class TestReflect {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>();
Method method = list.getClass().getMethod("add", Object.class);
method.invoke(list, "Java reflection mechanism instance."); System.out.println(list.get(0)); }}Copy the code
Retrieves and modifies the array information by reflection
package net.xsoftlab.baike; import java.lang.reflect.Array; public class TestReflect { public static void main(String[] args) throws Exception { 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("First element of array:" + Array.get(temp, 0));
Array.set(temp, 0, 100);
System.out.println(The first element of the array is:+ Array.get(temp, 0)); }}Copy the code
Modify the size of an array through reflection
package net.xsoftlab.baike; import java.lang.reflect.Array; public class TestReflect { public static void main(String[] args) throws Exception { int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; int[] newTemp = (int[]) arrayInc(temp, 15);print(newTemp);
String[] atr = { "a"."b"."c" };
String[] str1 = (String[]) arrayInc(atr, 8);
print(str1); Public static Object arrayInc(Object obj, int len) {Class<? > arr = obj.getClass().getComponentType(); Object newArr = Array.newInstance(arr, len); int co = Array.getLength(obj); System.arraycopy(obj, 0, newArr, 0, co);returnnewArr; } // Prints public static voidprint(Object obj) { Class<? > c = obj.getClass();if(! c.isArray()) {return;
}
System.out.println("Array length is:" + Array.getLength(obj));
for (int i = 0; i < Array.getLength(obj); i++) {
System.out.print(Array.get(obj, i) + ""); } System.out.println(); }}Copy the code
Apply reflection to the factory pattern
package net.xsoftlab.baike;
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();
}
returnf; }} /** * For normal factory mode when we add a subclass, we need to modify the factory class accordingly. When we add a lot of subclasses, it can get messy. Can refer to * http://baike.xsoftlab.net/view/java-factory-pattern * * * Java factory pattern now we use of reflection mechanism to realize the factory pattern, the factory class can be changed without add any number of subclasses. * * However, it is still a hassle to know the full package name and class name, which can be done using the Properties configuration file. * * read Java properties configuration file method can refer to * * * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file @author xsoftlab.net */ public class TestReflect { public static void main(String[] args) throws Exception { fruit f = Factory.getInstance("net.xsoftlab.baike.Apple");
if(f ! = null) { f.eat(); }}}Copy the code
# # to summarize
I reprint the format may not be so good, the original format is still great. Almost all of the common uses of reflection have been included above, which meets the technical requirements of our final goal – a custom awesome database framework, and more information that you can collect on your own.
In the next article, we’re going to look at annotations, those familiar annotations.