Learn spring must-learn Java Basics (1)----reflection (GO)

Source: Internet
Author: User
Tags throwable

QuoteTo learn the spring framework of the technical insider, you must master some basic Java knowledge, is the so-called "ascend will inferiority, involved in the far must from you." The following Java knowledge is closely related to the spring framework, and it's important to learn (I'll introduce these Java fundamentals through a series that I hope will help you.) ):

[1] Java Reflection knowledge-->spring ioc:http://www.iteye.com/topic/1123081
[2] Java dynamic agent-->spring aop:http://www.iteye.com/topic/1123293
[3] Property editor, Propertyeditor-->spring ioc:http://www.iteye.com/topic/1123628
[4] XML basic knowledge-->spring configuration: http://www.iteye.com/topic/1123630
[5] Annotations-->spring configuration: http://www.iteye.com/topic/1123823
[6] Thread local change, i.e. threadlocal-->spring transaction management: http://www.iteye.com/topic/1123824
[7] Transaction Fundamentals-->spring Transaction Management: http://www.iteye.com/topic/1124043
[8] Internationalization information-->mvc:http://www.iteye.com/topic/1124044
[9] HTTP message-->mvc:http://www.iteye.com/topic/1124408



The Java language allows programmatic indirect manipulation of classes, which are loaded by the class loader and form a description in the JVM.meta-Information object for class structure, this meta-information object can be used to learn the structure information of class:constructors, properties, and methodssuch as Java allows users to indirectly invoke the functionality of class objects by this class-related meta-information object, which opens the way to manipulating class objects programmatically.

Simple Example

We'll start with a simple example of the journey to the Java reflection mechanism, which has two constructors, two methods, and three properties, as shown in Listing 3-9:

Code Listing 3-9 Car

Java code
  1. Package com.baobaotao.reflect;
  2. Public class Car {
  3. private String brand;
  4. private String color;
  5. private int maxspeed;
  6. //① Default Constructors
  7. Public Car () {}
  8. //② with parametric constructors
  9. Public Car (String brand,string color,int maxspeed) {
  10. This.brand = brand;
  11. this.color = color;
  12. this.maxspeed = maxspeed;
  13. }
  14. //③ method with no parameters
  15. public Void introduce () {
  16. System.out.println ("Brand: +brand+"; color: "+color+"; maxspeed: "+maxspeed");
  17. }
  18. //Getter/setter method for omitting parameters
  19. ...
  20. }


In general, we will create an instance of car using the following code:

Java code
    1. Car car = new car ();
    2. Car.setbrand ("Red Flag CA72");


Or:

Java code
    1. Car car = new car ("Red Flag CA72","Black");



Both of these methods use the traditional method of directly invoking the target class, and we use the Java reflection mechanism to manipulate the target class indirectly in a more general way:

Code Listing 3-10 Reflecttest

Java code
  1. Package Com.baobaotao. Reflect
  2. Import Java.lang.reflect.Constructor;
  3. Import Java.lang.reflect.Field;
  4. Import Java.lang.reflect.Method;
  5. Public class Reflecttest {
  6. public static Car Initbydefaultconst () throws Throwable
  7. {
  8. //① getting car class objects by class loader
  9. ClassLoader loader = Thread.CurrentThread (). Getcontextclassloader ();
  10. Class clazz = Loader.loadclass ("Com.baobaotao.reflect.Car");
  11. //② Gets the default constructor object for the class and instantiates car through it
  12. Constructor cons = Clazz.getdeclaredconstructor ((class[])null);
  13. Car car = (car) cons.newinstance ();
  14. //③ Setting properties by Reflection method
  15. Method Setbrand = Clazz.getmethod ("Setbrand", String.           Class);
  16. Setbrand.invoke (Car,"Red Flag CA72");
  17. Method SetColor = Clazz.getmethod ("SetColor", String.   Class);
  18. Setcolor.invoke (Car,"Black");
  19. Method setmaxspeed = Clazz.getmethod ("Setmaxspeed",Int.Class);
  20. Setmaxspeed.invoke (car,200);
  21. return car;
  22. }
  23. public static void Main (string[] args) throws Throwable {
  24. Car car = Initbydefaultconst ();
  25. Car.introduce ();
  26. }
  27. }


Run the above program and the following information will be printed on the console:

Quoted brand: Red flag ca72;color: black; maxspeed:200



This means that we can programmatically invoke the functionality of class, which is consistent with the effect of invoking class functionality directly through constructors and methods, except that it is an indirect call, which is called directly.

In Reflecttest, several important reflection classes are used, namely ClassLoader, class, constructor, and method, which can indirectly invoke the functions of the target class. At ①, we get the classloader of the current thread, and then load the reflection instance corresponding to the Car class through the specified fully qualified class "Com.baobaotao.beans.Car". At ②, we get the car's constructor object cons by car's reflection class object, and the car object is instantiated by the Newinstrance () method of the constructor object, which is equivalent to the new car (). At ③, we get the Setter method object of the property through the GetMethod (String methodname,class Paramclass) of the reflection class object of car, the first parameter is the method name of the target class. The second parameter is the object type of the method entry. After the Get method reflects the object, the method of the target class can be called through the Invoke (Object Obj,object param) method, the first parameter of the method is the target class object instance of the operation, and the second parameter is the entry parameter of the target method.

In Code Listing 3 10, the information shown in bold is to manipulate the meta-information of the target class through the reflection method, and if we provide this information as a configuration file, we can use the Java language's reflection function to write a common code to instantiate and function invoke a class like car.

Class loader ClassLoader

class loader working mechanism

The class loader is looking for the class's section code file and constructs the component that the class represents the object within the JVM. In Java, the class loader loads a class into the JVM, taking the following steps:

        [1.] Loading: Finding and Importing class files;

        [2.] Link: Perform the validation, preparation and resolution steps, where the resolution step is optional:

        [2.1] Verification: Check the correctness of loading class file data;

        [2.2] Preparation: Assign storage space to static variables of class;

        [2.3] parsing: The symbolic reference is transferred to a direct reference;

        [3.] Initialization: Initialization of static variables and static blocks of code for a class.



Class loading work is the responsibility of ClassLoader and its subclasses, ClassLoader is an important Java Runtime system component that is responsible for locating and loading class bytecode files at run time. The JVM generates three ClassLoader at run time: the root loader, the Extclassloader (Extension class loader), and the Appclassloader (System class loader). Where the root loader is not a subclass of ClassLoader, it is written in C + +, so we do not see it in Java, the root loader is responsible for loading the JRE's core class library, such as Rt.jar, Charsets.jar, etc. under the JRE target. Both Extclassloader and Appclassloader are subclasses of ClassLoader. Where Extclassloader is responsible for loading the jar class package in the JRE extension directory ext; Appclassloader is responsible for loading the class package under the Classpath path.

There is a parent-child hierarchy between these three class loaders, that is, the root loader is the parent loader for Extclassloader, and Extclassloader is the parent loader for Appclassloader. By default, using Appclassloader to load an application's class, we can do an experiment:

Code Listing 3-11 Classloadertest

Java code
  1. Public class Classloadertest {
  2. public static void Main (string[] args) {
  3. ClassLoader loader = Thread.CurrentThread (). Getcontextclassloader ();
  4. System.out.println ("Current loader:" +loader);
  5. System.out.println ("Parent loader:" +loader.getparent ());
  6. System.out.println ("grandparent loader:" +loader.getparent ().  GetParent ());
  7. }
  8. }


Run the above code and the following information will be played on the console:

Quote current Loader:[email protected]
Parent Loader:[email Protected]
① root loader is not accessible in Java, so null is returned
Grandparent Loader:null



Through the above output information, we know that the current ClassLoader is Appclassloader, the parent ClassLoader is Extclassloader, grandfather ClassLoader is the root class loader, because in Java can not get its handle, Therefore, only null is returned.

The JVM loads the class using the "overall responsibility mechanism", "overall responsibility" refers to when a classloader load a class, unless explicitly using another ClassLoader, the class is dependent on and referenced by the class is also loaded by this classloader; "delegation mechanism" is to delegate the parent loader to look for the target class, and to find and load the target class from its own classpath only if it is not found. This is from a security perspective, just imagine how horrible it would be if someone wrote a malicious base class (such as java.lang.String) and loaded into the JVM. However, due to the "overall accountability mechanism", java.lang.String is always loaded by the root loader, thus avoiding the occurrence of the above event.

ClassLoader Important methods

In Java, ClassLoader is an abstract class that is located in the Java.lang package. Here are some important interface methods for this class:

      • Class loadclass (String name)
      • The name parameter specifies that the class loader needs to load the name of the class, and must use the fully qualified class name, such as Com.baobaotao. Beans. Car. The method has an overloaded method LoadClass (String name, Boolean resolve), and the Resolve parameter tells the class loader whether the class needs to be parsed. Before initializing a class, you should consider the work of class parsing, but not all classes need to be parsed, and if the JVM only needs to know if the class exists or finds a superclass of that class, then no parsing is required.

      • Class defineclass (String name, byte[] B, int off, int len)
      • Converts a byte array of a class file into a Java.lang.Class object inside the JVM. Byte arrays can be obtained from the local file system, the remote network. Name is the fully qualified class name that corresponds to the byte array.

      • Class Findsystemclass (String name)
      • Loading a class file from the local file system throws a ClassNotFoundException exception if the class file does not exist on the local file system. This method is the load mechanism used by the JVM by default.

      • Class Findloadedclass (String name)
      • Call this method to see if ClassLoader has mounted a class. Returns a Java.lang.Class object if it is mounted, otherwise null is returned. If you forcibly load a class that already exists, a link error will be thrown.

      • ClassLoader getParent ()
      • Gets the parent loader of the class loader, outside of the root loader, all class loaders have and only one parent loader, Extclassloader's parent loader is the root loader, because the root loader is not written in Java, so it cannot be obtained and will return null.



In addition to the JVM default of three ClassLoader, you can write your own third-party class loader to implement some special requirements. After the class file is loaded and parsed, it will have a corresponding Java.lang.Class class description object within the JVM, and the instance of the class has a reference to the class description object, and the class description object has a reference to the associated ClassLoader, as shown in 3-4.



Each class has a corresponding Java.lang.Class object in the JVM, which provides a description of the class structure information. arrays, enumerations, annotations, and basic Java types (such as int, double, and so on), even void have a corresponding class object. Class does not have a constructor method for public. Class objects are constructed automatically by the JVM by invoking the DefineClass () method in the class loader when the class is loaded.

java reflection mechanism

Class Reflection object describes the class semantic structure, You can get a reflection object from a class object, such as a constructor, member variable, method class, and so on, and programmatically manipulate the target class object through these reflection objects. These reflective object classes are defined in the Java.reflect package, and the following are the main three reflection classes:

      • ? Constructor: The class's constructor reflects the class, and the Class#getconstructors () method allows you to get an array of reflection objects for all constructors of the class. In JDK5.0, you can also get a constructor reflection object with a specific entry parameter through GetConstructor (Class ... parametertypes). One of the main methods of constructor is Newinstance (object[] initargs), which allows you to create an instance of an object class that is equivalent to the new keyword. In JDK5.0, the method evolves into a more flexible form: newinstance (Object ... initargs).
      • ? Method: Class method of Reflection class, through the Class#getdeclaredmethods () method can get all the methods of the class reflection class object array method[]. In JDK5.0, you can obtain a method of a specific signature by Getdeclaredmethod (String name, class ... parametertypes), name is the method name, class ... The list of parameter types for the method. The main methods of method are invoke (object obj, object[] args), obj represents the target object of the operation, args is the method entry, and code listing 3 shows how to use the Reflection class at 10③. In JDK 5.0, the method is adjusted to invoke (object obj, Object ... args). In addition, method has a number of ways to get more information about class methods:
      • 1) Class Getreturntype (): Gets the return value type of the method;

        2) class[] Getparametertypes (): Gets an array of parameter types for the method;

        3) class[] Getexceptiontypes (): Gets an array of exception types for the method;

      4) annotation[][] Getparameterannotations (): Gets the annotated information of the method, the new method in JDK 5.0;
    • ? Field: The reflection class of a member variable of a class, the Class#getdeclaredfields () method allows you to get an array of reflection objects of the class's member variables by Class#getdeclaredfield (String name) You can get a member variable reflection object of a specific name. The most important method of the field class is set (Object obj, object value), which obj represents the target object of the operation, and value is set for the member variable of the target object by value. If the member variable is the underlying type, the user can use the value of the type name provided in the field class to set the method, such as SetBoolean (Object obj, Boolean value), Setint (object obj, int value), and so on.


In addition, Java provides package reflection classes for packages, as well as annotatedelement reflection classes for annotations in JDK 5.0. In summary, the Java reflection system guarantees that all elements in the target class can be accessed programmatically, and for private or protected member variables and methods, as long as the security mechanism of the JVM permits, and can be invoked through reflection, see the following example:

Code Listing 3-12 Privatecarreflect

Java code
  1. Package com.baobaotao.reflect;
  2. Public class Privatecar {
  3. //①private member variables: Use traditional class instance invocation methods and can only be accessed in this class
  4. private String color;
  5. //②protected Method: Use traditional class instance invocation method, only in subclass and this package access
  6. protected Void Drive () {
  7. System.out.println ("Drive private car!  The color is: "+color);
  8. }
  9. }


Both the color variable and the drive () method are private and cannot be accessed externally by a class instance variable, and the private method is called, but this restriction can be bypassed through the reflection mechanism:

Code Listing 3-13 Privatecarreflect

Java code
  1. ...
  2. Public class Privatecarreflect {
  3. public static void Main (string[] args) throws throwable{
  4. ClassLoader loader = Thread.CurrentThread (). Getcontextclassloader ();
  5. Class clazz = Loader.loadclass ("Com.baobaotao.reflect.PrivateCar");
  6. Privatecar Pcar = (privatecar) clazz.newinstance ();
  7. Field colorfld = Clazz.getdeclaredfield ("color");
  8. //① Removing Java language access checks to access private variables
  9. Colorfld.setaccessible (true);
  10. Colorfld.set (Pcar,"Red");
  11. Method DRIVEMTD = Clazz.getdeclaredmethod ("Drive", (class[])null);
  12. //method DRIVEMTD = Clazz.getdeclaredmethod ("drive"); Use under JDK5.0
  13. //② Remove the Java language Access check to access the protected method
  14. Drivemtd.setaccessible (true);
  15. Drivemtd.invoke (Pcar, (object[])null);
  16. }
  17. }


Run the class and print out the following information:

Quote Drive Private car! The color is: red



The Java language check must be canceled through the setaccessible (Boolean access) method when accessing private, protected member variables, and methods, or illegalaccessexception will be thrown. If the security manager of the JVM has set the appropriate security mechanism, calling the method will throw SecurityException.

Learn spring must-learn Java Basics (1)----reflection (GO)

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.