First, reflection mechanism application scenario
It is important to know where to use it, and anything comes from him, knowing the scene to know why it was invented.
It is generally used when developing tools and frameworks related to Java language, such as the function name of a class, and then executing functions to implement dynamic invocation of the Class!
And so, all object-oriented languages may use this mechanism, the Prairie students do not support this mechanism, but can be implemented manually, please see the article of the Friends, http://blog.csdn.net/k346k346/article/details/51698184
Second, reflection mechanism
Let's go back to specifics about what a reflection mechanism is.
The Java Reflection mechanism provides the following functions: To determine the class to which any object belongs at run time, to construct an object of any class at run time, to determine the member variables and methods that any class has at run time, to invoke a method of any object at run time, and to generate a dynamic proxy.
A brief introduction to the commonly used methods of using reflection:
The point of attention when invoking a class method with reflection:
Method GetMethod () can only call a common method and cannot reflect the calling private method
Method Getdeclaredmethod () has access to all methods defined in this class, and method.setaccessible (true) is required to access the private method to obtain permissions
Take advantage of the launch to get the attention point of the property specified in the calling class:
Filed getfiled () Gets the public property specified in the class (including the base class)
Filed getdeclaredfiled () returns the properties of any visibility in the class (excluding base classes)
If you want to get the value of a non-public property of a base class, you can only invoke the method by reflection
On the Code
PackageTestImportjava.lang.reflect.*;/** * Base class Animal * /Class Animal { Public Animal() { } Public intLocationprotected intAgePrivate intHeightintLength Public int Getage() {returnAge } Public void Setage(intAge) { This. Age = Age; }Private int getheight() {returnHeight } Public void setheight(intHeight) { This. height = height; }}/** * Sub-class--dog * /Class Dog extends Animal { Public Dog() { } PublicString color;protectedString name;PrivateString type; String fur;} Public class test { Public Static void Main(string[] args) {System.out.println ("Hello world!"); Testrefect (); }Private Static void Testrefect() {Try{//Returns the properties of any visibility in the class (excluding base classes)System.out.println ("declared fileds:"); field[] fields = Dog.class.getDeclaredFields (); for(inti =0; i < fields.length; i++) {System.out.println (Fields[i].getname ()); }//Gets the public attribute specified in the class (including the base class)System.out.println ("public fields:"); Fields = Dog.class.getFields (); for(inti =0; i < fields.length; i++) {System.out.println (Fields[i].getname ()); }//getmethod () can only call a shared method and cannot reflect the calling private methodDog dog =NewDog (); Dog.setage (1); Method method1 = Dog.getclass (). GetMethod ("Getage",NULL); Object value = Method1.invoke (dog); System.out.println ("Age:"+ value);//Call the private type method of the base class /** First instantiates an animal object * /Animal Animal =NewAnimal (); Class a = Animal.getclass ();The GetHeight method in//animal is a private method and can only be used GetdeclaredmethodMethod method2 = A.getdeclaredmethod ("GetHeight",NULL); Method2.setaccessible (true);//java reflection cannot pass in a primitive type variable, as in the form intparam = A; class[] Argsclass =NewClass[] {int. class};The GetHeight method in//animal is a common method and can be used GetMethodMethod method3 = A.getmethod ("SetHeight", Argsclass); Method3.invoke (animal, param);The height variable in the//animal is declared as a static variable, which calls GetHeight () when a animal object is re-instantiated, and can also read the value of height intHeight = (Integer) method2.invoke (animal); System.out.println ("Height:"+ height);/** does not need to instantiate a animal, directly through reflection to obtain the Animal class object * /Class Anotheranimal = Class.forName ("Test. Animal ");The GetHeight method in//animal is a private method and can only be used GetdeclaredmethodMethod method4 = Anotheranimal.getdeclaredmethod ("GetHeight",NULL); Method4.setaccessible (true);//java reflection cannot pass in a primitive type variable, as in the form intParam2 = the; class[] ArgsClass2 =NewClass[] {int. class};The setheight method in//animal is a common method and can be used GetMethodMethod method5 = Anotheranimal.getmethod ("SetHeight", ARGSCLASS2); Method5.invoke (Anotheranimal.newinstance (), param2);The height variable in the//animal must be declared as a static variable so that getheight () is called after instantiating a animal object to read the value of height //Otherwise re-instantiates a new animal object, the value read is the initial value intHeight2 = (Integer) method4.invoke (Anotheranimal.newinstance ()); System.out.println ("Height:"+ height2); }Catch(Nosuchmethodexception e) {E.printstacktrace (); }Catch(InvocationTargetException e) {E.printstacktrace (); }Catch(Illegalaccessexception e) {E.printstacktrace (); }Catch(ClassNotFoundException e) {E.printstacktrace (); }Catch(Instantiationexception e) {E.printstacktrace (); } }}
Printing results:
Hello world!
Declared fileds:
Color
Name
Type
Fur
Public fields:
Color
Location
Age:1
Height:12
height:0
It is especially important to note that if you get all the original information of a class by reflection, including annotations (that's what spring does)
Class anotherAnimal = Class.forName("test.Animal");
The anotheranimal in the following statement contains all the original information for the Animal class, but the object that obtains the class requires the Newinstance () method
Method method5 = anotherAnimal.getMethod("setHeight", argsClass2); method5.invoke(anotherAnimal.newInstance(), param2);
At this point, we have a certain understanding of the use of reflection, so that in peacetime project development we can easily use the knowledge of reflection to call the encapsulation class of private methods and variables, while in the unit test can also test private methods.
————————————— Gorgeous split-line ———————————————
Iii. Modifying a String object with reflection
As we learn about Java, we understand that a string is an immutable object, such as the following code:
"Hello"; System.out.println("s = ""Welcome"; System.out.println("s = " + s);
Printing results are:
s = Hello
s = Welcome
First create a String object s, then set the value of S to "Hello", and then let s the value "Welcome". As you can see from the printout, the value of S has indeed changed. So how do you say the string object is immutable? In fact, there is a misunderstanding: s is just a reference to a string object, not the object itself. An object is an area of memory in memory, and the more member variables, the greater the amount of space that the memory area occupies. A reference is just a 4-byte data that contains the address of the object it points to, and the object can be accessed by this address.
That is, S is just a reference, it points to a specific object when s= "Welcome"; After the code executes, a new object is created, and the reference S re-points to the new object "Welcome", and the original object "Hello" still exists in memory.
So why is the string object immutable?
To understand the immutability of a string, first look at what member variables are in the string class. In JDK1.6, there are several member variables for string:
Public Final class String implements Java. io. Serializable, comparable, charsequence{ /** The value is used for character storage. * * Private Final CharValue[];/** The offset is the first index of the storage, that is used. * / Private Final intOffset/** The count is the number of characters in the String. * / Private Final intCount/** Cache The hash code for the string * / Private intHash//Default to 0
In Java, an array is also an object, value is a reference, it points to a real array object, the three variables of Value,offset and count are private, and no setvalue is provided. Public methods such as SetOffset and setcount to modify these values, so the string cannot be modified outside the string class. This means that once the initialization is not modified, and the three members cannot be accessed outside the string class. In addition, the three variables of Value,offset and count are final, that is, within the string class, once the three values are initialized, they cannot be changed. So you can think of a string object as immutable.
Is the string object really immutable?
From the above, it is known that the member variable of the string is private final, which is not changed after initialization. So in these few members, value is more special because he is a reference variable, not a real object. Value is final decorated, that is, final cannot point to other array objects, can I change the array that value points to? For example, change a character in an array to an underscore "_". At least not in the ordinary code we write ourselves, because we simply cannot access this value reference, nor can we modify the array by this reference.
So what is the way to access a private member? Yes, with reflection, you can reflect the Value property in a String object and change the structure of the array by the value reference obtained. Here is the instance code:
/** * String object is an immutable object, but you can modify the string object by using the Reflection method * / Public class testreflection { Public Static void Main(string[] args)throwsException {test (); } Public Static void Test()throwsException {String s ="Hello World"; System.out.println ("s ="+ s);//Gets the value object of stringField valuefieldofstring = String.class.getDeclaredField ("Value");//Change the Access property of valueValuefieldofstring.setaccessible (true);//Get the value of the Value property on the S object Char[] Value = (Char[]) Valuefieldofstring.get (s);//Change the 5th character of the array referenced by valuevalue[5] =' _ '; System.out.println ("s ="+ s); }}
Printing results are:
s = Hello World
s = Hello_world
In this process, s always refers to the same string object, but before and after the reflection, the string object has changed, that is to say, the so-called immutable object can be modified by reflection. But generally we do not do so. This example of reflection can also illustrate a problem: If an object, the state of his group of other objects can be changed, then this object is probably not immutable object. For example, a car object, which combines a wheel object, although the wheel object is declared as private final, but the internal state of the wheel object can be changed, it is not very good to ensure that the car object is immutable.
Iv. a blog supplement written by a Daniel
]
Java Learning: Reflection mechanism