Java reflection mechanism

Source: Internet
Author: User

Basic concepts

In the Java Runtime environment, for any class, can you know what the properties and methods of this class are? Can any one of its methods be called for any of the objects?

The answer is yes.

This dynamic acquisition of information for classes and the ability to dynamically invoke objects is derived from the Java language's reflection (Reflection) mechanism .

  

The Java reflection mechanism mainly provides the following features:

1. At run time, determine the class to which any one object belongs.

2. Constructs an object of any class at run time.

3. At run time, judge the member variables and methods that any one class has.

4. A method that invokes any object at run time.

Reflection is a key property of Java as a dynamic (or quasi-dynamic) language.

This mechanism allows the program to obtain the internal information of any given class with a known name through the reflection APIs at runtime.

Includes all information about its modifiers (such as public, static, and so on), superclass (such as object), interfaces implemented (such as Serializable), and its fields and methods. You can change the fields content or call methods at run time.

Dynamic language

Dynamic language definition "When a program is run, it allows you to change the program structure or variable type, which is called Dynamic language."

From this point of view, Perl,python,ruby is a dynamic language, and c++,java,c# is not a dynamic language.

Although Java is not a dynamic language under such definitions and classifications, it has a very prominent dynamic correlation mechanism: Reflection. The meaning of this word is: reflection, Image, reflection , used in Java refers to we can at runtime loading, detection, using the classes is completely unknown during compilation.

In other words, a Java program can load a runtime to know the name of the class, learn its full construct ( but not including the methods definition ), and generate its object entity, or its fields set value, or evoke its methods.

This ability to "see Through" class (the ability of the program to examine itself) is called introspection(introspection, vipassana, introspection). Reflection and introspection are the two terms that are often and are mentioned.

Introduction to the Java Reflection API

In the JDK, the Java reflection mechanism is implemented primarily by the following classes (except the first one) in the java.lang.reflect Package

   class: Represents a class that is located under the Java.lang package.

  Field class : Represents a member variable of a class (a member variable is also called a property of a class).

  Method Class : Methods that represent classes.

  Constructor class : Represents the construction method of a class.

  Array class : Provides a static method for dynamically creating an array, and for accessing the elements of an array.

Class object

To use reflection, you first need to get the class object corresponding to the classes you want to manipulate.

Java , regardless of how many objects of a class are generated, these objects will correspond to the same class object.

This class object is by the JVM generated, through which it is able to learn the structure of the entire class.

commonly used to get class 3 of Objects type of method:

  1. Use the static method of class. For example:

Class.forName ("java.lang.String");

  2. Use the. class syntax for the classes. such as:

String.class;

  3. Use the GetClass () method of the object . Such as:

String str = "AA"; class<?> classType1 = Str.getclass ();

The GetClass () method is defined in the object class, is not a static method, needs to be called through an object, and it is declared final, indicating that it cannot be overridden by a quilt class.

The class object ClassType obtained by direct print outputs:

Class full category name

If the GetName () method of the class object is called, the full class name is output and class is not added.

Routine 1: Getting methods

The routine Dumpmethods class demonstrates the basic role of the reflection API, which reads the class name specified by the command-line arguments, and then prints the method information that the class has.

Import Java.lang.reflect.method;public class dumpmethods{public    static void Main (string[] args) throws Exception// Add this sentence after the method, and the exception disappears    {        //Get the class object that is identified by the string        class<?> ClassType = Class.forName ("java.lang.String"); /Here the string to specify the class name, so the parameter gets can be a run-time behavior, you can use Args[0]                //Return class object corresponding to the classes or interfaces, the declared array of all methods (including private methods)        method[] methods = Classtype.getdeclaredmethods ();                Traverse output All method declaration for        (method Method:methods)        {            System.out.println (method);        }    }}

Routine 2: Calling a method by reflection

The method is called through reflection. See Code and notes for details:

Import Java.lang.reflect.method;public class invoketester{public int Add (int param1, int param2) {return PA    Ram1 + param2;    public string Echo (String message) {return "Hello:" + message; } public static void Main (string[] args) throws Exception {//previous normal execution means invoketester tester = new INV        Oketester ();        System.out.println (Tester.add (1, 2));        System.out.println (Tester.echo ("Tom"));        System.out.println ("---------------------------");  By the way of reflection///First step, Get class object//Before using the method is: Class.forName () method gets//here with the second method, class name. class<?>        ClassType = Invoketester.class;        To generate a new object: Use the Newinstance () method Object invoketester = Classtype.newinstance (); System.out.println (Invoketester instanceof Invoketester); Output true//By reflection call Method//First need to get the method object corresponding to the methods Addmethod = Classtype.getmethod ("Add", New Clas        S[] {int.class, int.class}); // The first parameter is the method name, and the second parameter is an array of class objects required by this method//Call the target method Object result = Addmethod.invoke (Invoketester, new object[]        {1, 2}); SYSTEM.OUT.PRINTLN (result); At this point, result is an integer type//Call to the second method Echomethod = Classtype.getdeclaredmethod ("echo", new class[]{        String.class});        Object result2 = Echomethod.invoke (invoketester, New object[]{"Tom"});    System.out.println (RESULT2); }}

Build Object

  To build an object by using the class's constructor without parameters, we have two ways:

1. Obtain the class object first, and then generate it directly from the Newinstance () method of the Class object:

     class<?> ClassType = String.class;     Object obj = classtype.newinstance ();

2. Obtain the class object first, then obtain the corresponding constructor object through the object, and then through the constructor object's Newinstance () method to generate

(where customer is a custom class with a parameterless constructor and a constructor with parameters):

    class<?> ClassType = Customer.class;    Gets the Constructor object, where    Constructor cons = Classtype.getconstructor (new class[] {}) is obtained for the first parameterless construction method;    Construct a method to generate an object    obj = cons.newinstance (new object[] {});

  If you want to build an object from a class's constructor with parameters, you can only use one of the following methods:

(Customer is a custom class with a constructor with no arguments, and a constructor with parameters, passing in strings and integers)

    class<?> ClassType = Customer.class;    Constructor cons2 = Classtype.getconstructor (new class[] {string.class, int.class});    Object obj2 = cons2.newinstance (new object[] {"Zhangsan", 20});

You can see that calling the constructor method to build the object is similar to calling a generic method, unlike getting a constructor object from a class object without specifying a name and specifying a name when getting the method object.

An example of using reflection to copy objects

The following routine Reflecttester class further demonstrates the basic use of the reflection API.

The Reflecttester class has a copy (Object object) method that creates an object of the same type as the Parameter object, and then copies all the properties in the object to the newly created object and returns it.

This example can only copy a simple class, assuming that each property of the class has the getxxx () and Setxxx () methods of the public type.

  

Import Java.lang.reflect.constructor;import Java.lang.reflect.field;import Java.lang.reflect.method;public class reflecttester{//This method implements a copy operation to the Customer object public, Object copy (Object object) throws Exception {class<?> ClassType = Object.getclass ();Object objectcopy = ClassType.GetConstructor(New class[]{}).newinstance(New object[]{});        Get all member variables of the object field[] fields = Classtype.getdeclaredfields ();    for (Field field:fields) {//Gets the name of the member variable String name = Field.getname ();    Gets the name of the member variable, here Id,name,age//Gets the name of the Get and set method String Firstletter = name.substring (0,1). toUpperCase ();            Converts the first letter of the property to uppercase String Getmethodname = "Get" + Firstletter + name.substring (1); String setmethodname = "Set" + Firstletter + name.substring (1);//Get Method Object Methods GetMethod = Classtype.getmethod (Getmethodname, New class[]{});                        Method Setmethod = Classtype.getmethod (Setmethodname, New Class[]{field.gettype ()});//Note the Set method needs to pass in the parameter type            Call the Get method to get the value of the old object, object value = Getmethod.invoke (object, New object[]{}); Call the Set method to copy this value to the new object Setmethod.invoke (Objectcopy, New Object[]{value});} return objectcopy;        public static void Main (string[] args) throws Exception {Customer customer = new Customer ("Tom", 20);        Customer.setid (1L); Reflecttester tester = new Reflecttester ();Customer Customer2 = (customer) tester.copy (customer);            System.out.println (Customer2.getid () + "," + customer2.getname () + "," + customer2.getage ());    }}class customer{private Long ID;    private String name;    private int age;        Public customer () {} public customer (String name, int age) {this.name = name;    This.age = age;    } public Long GetId () {return id;    } public void SetId (long id) {this.id = ID;    } public String GetName () {return name;    } public void SetName (String name) {this.name = name;    } public int Getage () {return age;    public void Setage (int.) {this.age = age; }}

Reflections and Arrays

The Java.lang.Array class provides a variety of static methods for dynamically creating and accessing array elements.

The main () method of the ArrayTester1 class creates a string array of length 10, then sets the element with index position 5 to "hello", and then reads the value of the element with index position 5.

  

Import Java.lang.reflect.array;public class arraytester1{public    static void Main (string[] args) throws exception< c1/>{        class<?> ClassType = Class.forName ("java.lang.String");                Generates an array, specifying the element type and array length of        Object array = array.  Newinstance(ClassType, ten);                Array.set (Array, 5, "Hello");        String str = (string) array.get (Array, 5);                System.out.println (str);}                    }

Multidimensional arrays

First, distinguish between the following:

System.out.println (integer.type);   System.out.println (Integer.class);

Output:

Int

Class Java.lang.Integer

A program instance of a multidimensional array:

  

Import Java.lang.reflect.array;public class arraytester2{public static void Main (string[] args) {int[] dims        = new Int[] {5, 10, 15};    Note the following two kinds of System.out.println (integer.type) are differentiated;    int System.out.println (integer.class);        Integer//Create a three-dimensional array, the three dimensions of this array are 5,10,15 Object array = array.newinstance (Integer.type, dims);        Variable parameters can also be written like this://Object array = array.newinstance (Integer.type, 5,10,15);                System.out.println (array instanceof int[][][]);    class<?> CLASSTYPE0 = Array.getclass (). Getcomponenttype ();    Returns the array element type SYSTEM.OUT.PRINTLN (CLASSTYPE0);        The elements of a three-dimensional array are two-dimensional arrays, Output: class [I//Get an array of index 3 for the first layer, and return a two-dimensional array of Object Arrayobject = Array.get (array, 3);    class<?> ClassType = Arrayobject.getclass (). Getcomponenttype ();    Returns the array element type SYSTEM.OUT.PRINTLN (ClassType); The elements of a two-dimensional array are one-dimensional arrays, and the output: class [I//) returns a one-dimensional array arrayobject = Array.get (Arrayobject, 5);    class<?> classType2 = Arrayobject.getclass (). Getcomponenttype ();    Returns the array element type SYSTEM.OUT.PRINTLN (CLASSTYPE2);        The elements of a one-dimensional array are int//The position of a one-dimensional array labeled 10 is set at the value of Array.setint (Arrayobject, 10, 37);        Int[][][] Arraycast = (int[][][]) array;    System.out.println (arraycast[3][5][10]); }}

Calling private methods with reflection, accessing private properties

With reflection, the first is the acquisition of the class object, followed by the method and the Field object.

In the case of method, you can see from the documentation:

The GetMethod () method returns the public method object,

The method object returned by Getdeclaredmethod () can be non-public.

field is the same way.

  access to private properties and methods to suppress Java access checks by using the Setaccessible () method in the AccessibleObject class (the base class of the Constructor, field, and method classes) before use .

Instance 1, calling private method

Suppose you have a class that contains a private method.

public class privateclass{    privatestring SayHello (string name)    {        return "Hello:" + Name;    }}

  use the reflection mechanism to access the method externally :

Import Java.lang.reflect.method;public class testprivate{public    static void Main (string[] args) throws exception< c1/>{        Privateclass p = new Privateclass ();        P.getclass ();        Get Method Object Method        = Classtype.getdeclaredmethod ("SayHello",                new class[] {string.class});        method.setaccessible (TRUE);//Suppress access control checks        for Java //If you do not add the above sentence, you will error:testprivate can not access a member of class Privateclass with modifiers "private"        String str = (string) Method.invoke (p, new object[] {"Zhangsan"});        System.out.println (str);}    }


Instance 2, accessing private properties

Direct access to private properties, changing the value of the private property in the example.

A class that contains a private property:

public class privateclass2{    privateString name = "Zhangsan";    Public String getName ()    {        return name;    }}

Modify the value of its private property with reflection:

Import Java.lang.reflect.field;public class testprivate2{public    static void Main (string[] args) throws exception< c8/>{        PrivateClass2 p = new PrivateClass2 ();        class<?> ClassType = P.getclass ();        Field field = Classtype.getdeclaredfield ("name");        Field.setaccessible (TRUE); Suppresses Java's checking of modifiers        field.set (p, "Lisi");        System.out.println (P.getname ());}    }

class

The Object class in Java is the source of inheritance for all classes, where the getclass () method returns a class Object. All classes have this method.

   class is very special, and it inherits from object like other classes, in fact the body is used to express the Java program runtime classes and interfaces, but also to express the enum, array, primitive Java Types (Boolean, Byte, char, short, int, long, float, double) and keyword void.

When a class is loaded, or when the defineclass () of the Loader (class loader) is called by the JVM, the JVM automatically generates a Class object.

If you want to change the Java standard Library source code to observe the actual generation time of the class object, such as adding println () in the class constructor, it is not possible. Because class does not have public constructor.

Class is the origin of reflection. For any class that you want to explore, you only have to create a class object for it before you can evoke more than 10 reflection APIs through the latter.

The way to get the "Class" object

  1. Use the GetClass () method to return the class object.

Use Class.getsuperclass () to get the class object of the parent class and return NULL if it is an object class.

  2. Using static method Class.forName ()

  3. Use the. class syntax. Class name.

The class object of the shaping array can also be obtained in the form of Int[].class.

Wrapper class . The type syntax actually returns a class object of the corresponding native data type.

Java reflection mechanism

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.