A deep understanding of Java reflection and a deep understanding of java

Source: Internet
Author: User
Tags object serialization

A deep understanding of Java reflection and a deep understanding of java

To understand the principles of reflection, you must first understand what type information is. Java allows us to identify the object and class information at runtime, mainly in two ways: one is the traditional RTTI, which assumes that we already know all the types of information during compilation; the other is the reflection mechanism, which allows us to discover and use class information at runtime.

1. Class Object

To understand how RTTI works in Java, you first need to know how the type information is represented at runtime. This is done by the Class object, which contains information related to the Class. Class objects are used to create all "regular" objects. Java uses Class objects to execute RTTI, even if you are performing operations similar to type conversion.

Each Class generates a corresponding class object, that is, it is stored in the. Class file. All classes are dynamically loaded to the JVM when they are used for the first time. When a program creates a reference to a static member of the class, the class is loaded. Class objects are loaded only when needed, and static Initialization is performed during Class loading.

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 constructed ");}}

Output result:

The Class Loader first checks whether the class object of this Class has been loaded. If not, the default class Loader searches for the corresponding. Class file based on the class name.

To use the type information during runtime, you must obtain the reference of the Class Object of the object (such as the Class Base object) and use the function Class. forName ("Base") can be used for this purpose, or base. class. Note: It is interesting to note that when the function ". class" is used to create a Class Object reference, this Class object will not be automatically initialized, and the Class object will be automatically initialized using forName. The following three steps are generally taken to prepare for the use of classes:

  • Loading: completed by the Class loader. Find the corresponding bytecode and create a Class object.
  • Link: the bytecode in the verification class, which allocates space for the static domain
  • Initialization: If this class has a super class, initialize it and execute the static initialization tool 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) {// static block Class clazz1 = Base is not initialized. class; System. out. println ("------"); // Class clazz2 = Class will be initialized. forName ("zzz. base ");}}
2. Check Before type conversion

The compiler checks whether the type downward transformation is valid. If the type is invalid, an exception is thrown. You can use instanceof to determine the type before downgrading.

Class Base {} class Derived extends Base {} public class Main {public static void main (String [] args) {Base base = new Derived (); if (base instanceof Derived) {// The System can be converted down here. out. println ("OK");} else {System. out. println ("not OK ");}}}
3. Reflection: runtime class information

If you do not know the exact type of an object, RTTI can tell you, but there is a premise that this type must be known during compilation so that you can use RTTI to identify it. Class and java. lang. the reflect Class Library supports reflection. The class library contains the Field, Method, and Constructor classes. These class objects are created at JVM startup to indicate the corresponding members of the unknown class. In this way, you can use Contructor to create a new object, use the get () and set () methods to obtain and modify the fields associated with the Field object in the class, and use invoke () call the Method associated with the Method object. In addition, you can call many convenient methods such as getFields (), getMethods (), and getConstructors () to return arrays representing fields, methods, and constructors, the object information can be completely determined at runtime, but you do not need to know anything about the class during compilation.

There is no magic in the reflection mechanism. When dealing with an unknown object through reflection, JVM simply checks this object to see which specific class it belongs. Therefore,.classFor JVM, it must be accessible either on the local machine or from the network. So the real difference between RTTI and reflection is:

  • RTTI, the compiler opens and checks the. class file during compilation
  • Reflection, opening and checking the. class file during runtime
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", 23); Class clazz = person. getClass (); Field [] fields = clazz. getDeclaredFields (); for (Field field: fields) {String key = field. getName (); PropertyDescriptor descriptor = new PropertyDescriptor (key, clazz); Method = descriptor. getReadMethod (); Object value = method. invoke (person); System. out. println (key + ":" + value );}}

The getReadMethod () method is used to call the get function of the class. You can call the set Method of the class through the getWriteMethod () method. Generally speaking, we do not need to use reflection tools, but they are more useful in creating dynamic code. Reflection is used in Java to support other features, such as object serialization and JavaBean.

4. Dynamic proxy

The proxy mode is used to provide additional or different operations, and is inserted to replace "actual" objects. These operations involve communication with "actual" objects, therefore, the proxy usually acts as the intermediary. Java's dynamic proxy is a step forward than the idea of proxy. It can dynamically create and act as a proxy and dynamically process calls to the proxy method. All calls made on the dynamic proxy will be redirected to a singleCall ProcessorIt is used to reveal the call type and determine the corresponding policy. The following is an example of 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 processor:

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 ("the agent is working. "); 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 result is as follows:

By calling the Proxy static method Proxy. newProxyInstance () can create a dynamic proxy. This method requires a class loader, a list of interfaces (not classes or abstract classes) that you want the proxy to implement, and an implementation class of InvocationHandler. The dynamic proxy can redirect all calls to the calling processor. Therefore, it usually calls the processor's constructor to pass a reference to an "actual" object, so that when the calling processor executes a mediation task, forward requests.

 

Refer:

1. Java programming ideology-section 4th on type information

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.