--java Training, Android training, iOS training,. NET training, look forward to communicating with you! ——
I. Overview
The Java reflection mechanism is in the running state, and for any class in the program, all properties and methods of the class, including common, inclusive, default, and private, can be known through the reflection mechanism. For any one object, each of its methods can be called through the reflection mechanism, which is called the Java Reflection mechanism. The general operation is in the java.lang.reflect
package, common to the class has Constructor
, Field
and Method
three kinds. Since it is a reflection of the Java class, of course, there is a class, Class
which is also a class, as a class in the class Java
file, get class classes generally have three ways:
"abc";// 通过类直接获取Class<?> c1 = String.class;// 通过变量的getClass()方法获取Class<?> c2 = s.getClass();// 通过Class的静态方法forName(String)根据类的全名获取Class<?> c3 = Class.forName("java.lang.String");
So what is the use of the reflection mechanism in Java? General program Development, we are the use of the class direct operation, such as create, but if it is not possible to do direct operation, this is a reflection of the usefulness, such as but according to a class name of the string to get an instance of the class, which is also a use, the program can be based on the class name within the configuration file to create different classes There are also cases where there are private methods in the class that we want to access or modify, and that normal practice does not work, and it can be achieved by reflection, which is also a violent reflex.
Two
Class
Class
The first time you see this class can be a bit confusing, there are many classes in Java, there are many used, but the first time to see this class class, how much is a bit curious, it is also more proof that all things can be described as objects, since the class is so common, it is certainly no exception. First, we should have some preliminary understanding of the class file, we use to compile after the code, we javac
can see the directory .java
of files generated by the file .class
, then these .class
files are class files. When these files are executed, such as the java x.class
class file is loaded into memory for use, the other classes used in the class file are also loaded, and the following example results illustrate the problem that class files are unique in memory.
"abc";System.out.println(a1.getClass() == String.class);System.out.println(a1.getClass() == Class.forName("java.lang.String"));// 执行结果为truetrue
For basic data Types boolean,char,byte,short,int,long,float,double
a total of 8 and one void
have their corresponding classes, such as Int.class
, note int.class
and Integer.class
are not of the same class. For arrays also have their corresponding classes, such as Int[].class
, int[][].class
, the same type, and the same array class with the same number of dimensions, that is, int[].class! = int[] [].class
, other similar, the class name of the array class has a certain rule, such as int[][].class.getname ()
returns [[I
, where [
Number represents the dimension, int
corresponds to I
, and the corresponding relationship is as follows:
type name |
the corresponding content |
Boolean |
Z |
Byte |
B |
Char |
C |
Double |
D |
Float |
F |
Int |
I |
Long |
J |
Short |
S |
Class or interface |
Lclassname |
The array class is also inherited from, such as Object
can be received with the Object
object, int[]
such as Object obj = new int[]{1, 2, 3};
, but note that Object[] obj = new int[]{1, 2, 3};
this is not correct, because the basic data type cannot be converted to an Object
object.
Class
Common methods of
-
getconstructor (class<?> parametertypes)
This method is used to get the constructor of the class, where the parameter is a mutable parameter that specifies the constructor method that gets, If you get the string (StringBuilder StringBuilder)
construction method of the string
class, you can use the Constructor cons String.class.getConstructor (stringbuilder.class);
Way to get it. Another way to get a multi-construct method like this one is getconstructors ()
, which can get all the constructor methods and return an array of Constructor
. The
-
newinstance ()
method is used to instantiate an object, that is, to create an object with that class. The sample code is as follows:
import Java.lang.reflect.*;class Main {public static void main (string[] args) throws Exception {//Gets a construction method of String Constructor cons = String.class.getConstruc Tor (Stringbuilder.class); System.out.println (cons); //Create an empty string String s = String.class.newInstance (); System.out.println (s); }}//execution result is public Java.lang. string (Java.lang.StringBuilder) [Empty string]
String getName()
Used to get the class name (containing the package name), such as String.class.getName()
the return value "java.lang.String"
.
Package getPackage()
Used to return the package name.
Field getField(String name)
Gets the member variable of the class.
Field[] getFields()
Gets the class that sends all accessible member variables.
Field getDeclaredField(String name)
Gets a member variable of the class declaration by name. You can get private
the decorated member variables here, as well as the Field[] getDeclaredFields()
member variables used to get all the class declarations.
Method getMethod(String name, Class<?>... parameterTypes)
Getting a method, like getting a constructor method, also has the method of getting all the methods and getting the declaration, and so on.
Three
Constructor
Class<T> getDeclaringClass()
Returns a Class object that represents the classes that declare the construction method represented by this Constructor object.
int getModifiers()
Returns the Java language modifier that returns the constructed method represented by this Constructor object as an integer.
T newInstance(Object... initargs)
Use the constructor method represented by this Constructor object to create a new instance of the Declaration class for the constructed method, and initialize the instance with the specified initialization parameters.
ImportJava.lang.reflect.*;class Main { Public Static void Main(string[] args)throwsException {//Gets a construction method of stringConstructor cons = String.class.getConstructor (Stringbuilder.class);//using the Get constructor to instantiate an objectstring s = (string) cons.newinstance (NewStringBuilder ("ABC"));//Output This objectSystem.out.println (s);//Gets the class corresponding to the constructor functionclass<?> C = Cons.getdeclaringclass ();//Output class nameSystem.out.println (C.getname ());//Type of construction methodSystem.out.println (member.declared = = Cons.getmodifiers ()); }}
Four
Field
Describes a member of a class, the general function is to get the value of this member, set the value of the member, get the data type of the member, and so on, the following is a demonstration Field
of the relevant operation, the instance content for a custom object in the member ( String
type) of the occurrences of the overlapping words [double]
, The first is the class object that gets the custom object, then gets all the declared members, gets the values of those members, and then sets the replaced value back.
Importjava.lang.reflect.*;/** * Replaces two consecutive * identical characters appearing in a member variable (string type) in a custom class with [double]. As AA becomes [double]. */Class Main { Public Static void Main(string[] args)throwsException {Demo demo =NewDemo ();//Gets the members of the Declaration in the demo objectfield[] fields = Demo.getclass (). Getdeclaredfields (); for(Field field:fields) {//If it is not directly accessible, modify it to a directly accessible type if(!field.isaccessible ()) {field.setaccessible (true); }//Get raw string contentsString oldstring = (string) field.get (demo);//Replace the overlapping words with [double]String newstring = Oldstring.replaceall ("(.) \\1 ","[Double]");//finally set the new string backField.set (demo, newstring);//Output new variable contentsSystem.out.println (field); } System.out.println (Demo.tostring ()); }}class Demo {//modified should be Ac[double]de PublicString A ="ABCCDE";//modified should be He[double]oawdcs PrivateString B ="Helloawdcs";//modified should be [Double]sdn[double]asdnjasd[double]adas protectedString C ="Aasdnjjasdnjasdbbadas"; PublicStringtoString() {returnA +"/"+ B +"/"+ C; }}
Five
Method
Describes a method of a class, commonly used functions, class<?> getreturntype ()
returns a class
object that describes this Method The formal return type of the method represented by the
object. object Invoke (Object obj, object ... args)
invokes the underlying method represented by this method
object for the specified object with the specified argument. The following is an example of a character that gets the first position of a String
object through the reflection function, called the charAt ()
method.
import java.lang.reflect.*;class Main { public static void main(String[] args) throws Exception { String s = "abc"; // 获取String的类对象 Class<?> c = String.class; // 获取String类的charAt方法 Method method = c.getMethod("charAt", int.class); // 通过方法的反射获取第1个位置的字符 char ch = (char)method.invoke(s, 1); System.out.println(ch); // 结果为b }}
Vi. Reflection of arrays
When using reflection to pass an array parameter, it is important to note that it may be automatically split into the corresponding variable parameter type, such as main
the method String[]
will become String...
, so there are generally two ways to solve the transfer, one is to encapsulate it again into an array, such as new Object[]{new String[]{"abc", "cba", "bac"}}
; (Object)new String[]{"abc", "cba", "bac"}
, both methods are available.
Importjava.lang.reflect.*;/** * Invokes the main method of another class by reflection, passing an array parameter */Class Main { Public Static void Main(string[] args)throwsException {//Get the class object of the corresponding classes firstClass clazz = Demo.class;//Get the Main method of demomethod = Clazz.getmethod ("Main", String[].class);//define parameters to be passedstring[] STRs =Newstring[]{"Hello","Hi","Bye"};/* When calling a static method, you do not need to pass the variable * Note: Because of the JDK version, if the direct delivery of STRs will be split into a variable type string ..., does not conform to the parameters of main, so * here to a whole, obje CT type * /Method.invoke (NULL, (Object) STRs); }}class Demo { Public Static void Main(string[] args) {//parameter output to be passed in for(String S:args) {System.out.println ("Parameters:"+ s); } }}//Execution ResultsParameters: Hello parameter: Hi parameter: Bye
As mentioned earlier, arrays are also a class, such as int[].class
there are some differences between this class and other classes, Java provides a class for manipulating array classes, and the Array
array class provides methods for dynamically creating and accessing Java arrays. Array allows extended conversions during a get or set operation, but throws if a narrowing conversion occurs IllegalArgumentException
. The sample code is as follows:
Importjava.util.*;ImportJava.lang.reflect.*;class Main { Public Static void Main(string[] args)throwsException {//Get string[] corresponding classclass<?> clazz = String[].class;//define a string array and initializestring[] STRs =Newstring[]{"Hello","Hi","Bye"};//If this class is an array class if(Clazz.isarray ()) {//Gets the length of the array intLen = Array.getlength (STRs);//variable this array for(intI=0; i<len; i++) {//Reflection Gets the value of position I of STRsstring s = (string) array.get (STRs, i);//output Gets the valueSystem.out.println (i+":"+s);//If this value is hi, change it to good if(S.equals ("Hi") {Array.set (STRs, I,"Good"); } }//The entire array is outputSystem.out.println (arrays.tostring (STRs)); } }}//Execution result is0: Hello1: Hi2: Bye[hello, good, Bye]
VII. Application of Reflection
In actual development, the application of reflection is generally used for the development of the framework, the framework is the core extraction of some functions, covering the whole of a system, but do not complete the details of things.
The following is an instance of a framework, the program can be based on the user configuration of the file, the execution of the use of different classes, in the current directory to establish a file name config.properties
in the Write className=java.util.ArrayList
, which is the program in the collection is used ArrayList
, the final result is the collection size of 4, and then className
the value is modified to java.util.HashSet
, the final result becomes 3, so that the program can use different classes depending on the configuration, the framework is so, when the class used is not deterministic, or no ready-made classes can be used, do not use reflection to implement program functions. The code is as follows:
Importjava.io.*;Importjava.util.*;ImportJava.lang.reflect.*;class Main { Public Static void Main(string[] args)throwsException {//ConfigurationProperties Properties =NewProperties ();//Get the input stream through the class loaderInputStream in = Main.class.getResourceAsStream ("Config.properties");//Load the configuration from the streamProperties.load (in);//Close streamIn.close ();//Get class nameString className = Properties.getproperty ("ClassName");//Get class by class nameClass clazz = Class.forName (className);//Based on the Clazz class, create a Collection objectCollection Collection = (Collection) clazz.newinstance ();//Add some strings to the collectionCollection.add (NewString ("Hello")); Collection.add (NewString ("Hi")); Collection.add (NewString ("Bye")); Collection.add (NewString ("Bye"));//The size of the output collectionSystem.out.println (Collection.size ()); }}
Dark Horse programmer-java reflex