Deep understanding of Java Reflection

Source: Internet
Author: User

To understand the principle of reflection, you first need to understand what type information is. Java allows us to identify objects and classes at run time, mainly in 2 ways: One is the traditional rtti, which assumes that we already know all the type information at compile time, and the other is the reflection mechanism, which allows us to discover and use the information of the class at run time.

1. Class object

To understand how Rtti works in Java, you first need to know how the type information is represented at run time, which is done by the class object, which contains information about the class. The class object is used to create all "regular" objects, and Java uses the class object to perform Rtti, even if you are doing something like type conversion.

Each class will produce a corresponding class object, which is saved in the. class file. All classes are dynamically loaded into the JVM when they are first used, and the class is loaded when the program creates a reference to a static member of the class. The class object is loaded only when needed, and static initialization occurs when the class is loaded.

public class Testmain {public    static void Main (string[] args) {        System.out.println (xyz.name);}    } Class XYZ {public    static String name = "Luoxn28";    static {        System.out.println ("xyz static Block");    }    Public xyz () {        System.out.println ("xyz constructs");}    }

The output is:

The class loader first checks to see if the class object has been loaded, and if it is not already loaded, the default ClassLoader will look for the corresponding. class file based on the class name.

To use type information at run time, you must get a reference to the class object of the object (such as the class base object), use the function class.forname ("base") for that purpose, or use Base.class. It is interesting to note that when you use the function ". Class" To create a reference to a class object, the class object is not automatically initialized, and the class object is automatically initialized with forname (). The following 3 steps are generally used to prepare for the use of a class:

    • Load: Done by the ClassLoader, find the corresponding bytecode, create a class object
    • Links: Validating bytecode in classes, allocating space for static domains
    • Initialize: If the class has a superclass, initialize it, execute the static initializer and static initialization block
public class Base {    static int num = 1;        static {        System.out.println ("Base" + num);}    } public class Main {public    static void Main (string[] args) {        //does not initialize static block        class clazz1 = Base.class;        SYSTEM.OUT.PRINTLN ("------");        Initializes        Class clazz2 = Class.forName ("zzz"). Base ");}    }
2. Check before type conversion

The compiler will check whether the type down is legal and throws an exception if it is not legal. You can use instanceof to judge the type before you convert it down.

Class Base {}class Derived extends base {}public class Main {public    static void Main (string[] args) {        base ba SE = new Derived ();        if (base instanceof Derived) {            //Here you can convert down            System.out.println ("OK");        }        else {            System.out.println ("not OK");}}}    
3. Reflection: Run-time class information

If you do not know the exact type of an object, Rtti can tell you, but there is a precondition: This type must be known at compile time to use Rtti to identify it. The class class supports reflection with the Java.lang.reflect class library, which contains the field, method, and constructor classes, which are created by the JVM at startup to represent the corresponding members of the unknown class. This allows you to create new objects using Contructor, get and modify the fields associated with the Field object in the class with the Get () and set () methods, and invoke the methods associated with the method object with the Invoke () method. In addition, many convenient methods, such as GetFields (), GetMethods (), and GetConstructors (), can be called to return an array of fields, methods, and constructor objects so that object information can be fully determined at run time. And you don't need to know anything about the class at compile time.

The reflection mechanism is nothing magical, and when dealing with an object of unknown type through reflection, the JVM simply examines the object to see which particular class it belongs to. Therefore, the class must be available to the .class JVM, either on the local machine or from the network. So the real difference between Rtti and reflection is only that:

    • RTTI, the compiler opens and checks the. class file at compile time
    • Reflection, run-time open and check. class files
public class Person implements Serializable {    private String name;    private int age;//Get/set method}public static void Main (string[] args) {person person    = new Person ("luoxn28", +);    Class clazz = Person.getclass ();    field[] fields = Clazz.getdeclaredfields ();    for (Field field:fields) {        String key = Field.getname ();        PropertyDescriptor descriptor = new PropertyDescriptor (key, clazz);        Method method = Descriptor.getreadmethod ();        Object value = Method.invoke (person);        SYSTEM.OUT.PRINTLN (key + ":" + value);}    }

The Get function of the class is called by the Getreadmethod () method, and the set method of the class can be called Through the Getwritemethod () method. In general, we don't need to use the reflection tool, but they are more useful in creating dynamic code that is reflected in Java to support other features, such as serialization and JavaBean of objects.

4. Dynamic Agent

The proxy pattern is intended to provide additional or different operations, whereas objects inserted to replace "real" objects involve communication with the "actual" object, so the agent typically acts as a middleman. The dynamic agent of Java is a step ahead of the idea of the agent, which dynamically creates and proxies and dynamically handles calls to the proxy method. All calls made on the dynamic agent are redirected to a single calling processor , and its job is to reveal the type of invocation and determine the appropriate policy. The following is an example of a dynamic proxy:

Interfaces and implementation classes:

Public interface Interface {    void dosomething ();    void SomethingElse (String arg);} public class Realobject implements Interface {public    void dosomething () {        System.out.println ("dosomething.");    }    public void SomethingElse (String arg) {        System.out.println ("SomethingElse" + arg);}    }

Dynamic Proxy Object Handler:

public class Dynamicproxyhandler implements Invocationhandler {    private Object proxyed;        Public Dynamicproxyhandler (Object proxyed) {        this.proxyed = proxyed;    }        @Override Public    object Invoke (Object proxy, Method method, object[] args) throws Illegalaccessexception, IllegalArgumentException, InvocationTargetException {        System.out.println ("Agent worked.");        Return Method.invoke (proxyed, args);}    }

Test class:

public class Main {public    static void Main (string[] args) {        realobject real = new Realobject ();        Interface proxy = (Interface) proxy.newproxyinstance (                Interface.class.getClassLoader (), new class[] { Interface.class},                new Dynamicproxyhandler (real));                Proxy.dosomething ();        Proxy.somethingelse ("Luoxn28");}    }

The output results are as follows:

By calling the proxy static method Proxy.newproxyinstance () You can create a dynamic proxy, which requires a class loader, a list of interfaces (not classes or abstract classes) that you want the proxy to implement. and an implementation class for Invocationhandler. Dynamic agents can redirect all calls to the calling processor, so the handler's constructor is typically called to pass a reference to an "actual" object, which forwards the calling processor when it executes the mediation task.

Reference:

1. "Java Programming Idea-4th Edition" type Information section

Deep understanding of Java Reflection

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.