Java Reflection Mechanism Instance tutorial _java

Source: Internet
Author: User
Tags modifier modifiers reflection throwable

This paper describes the reflection mechanism of Java in detail, which is an important technique in Java programming. Share to everyone for your reference. The specific analysis is as follows:

First of all, reflection is one of the features of Java Program Development language, it allows the running Java program to check itself, or "self audit", and can directly manipulate the internal properties of the program . For example, you can use it to get the names of the members in the Java class and display them. This capability of Java may not be used in many practical applications, but it does not exist in other programming languages at all. For example, there is no way in Pascal, C, or C + + to get information about function definitions in a program.

JavaBean is one of the practical applications of reflection, which allows some tools to visualize the operation of software components. These tools dynamically load and get the properties of the Java component (Class) by reflection .

1. A simple example

Consider the following simple example, let's see how reflection works.

Import java.lang.reflect.*; 
public class Dumpmethods {public 
  static void Main (String args[]) { 
   try { 
      Class C = Class.forName ("Java.util.s Tack "); 
      Method m[] = C.getdeclaredmethods (); 
      
      for (int i = 0; i < m.length i++) 
        System.out.println (m[i].tostring ()); 
   } 
   catch (Throwable e) { 
      System.err.println (e); 
   } 
  } 
}

Its result output is:

Public synchronized Java.lang.Object Java.util.Stack.pop () public
java.lang.Object Java.util.Stack.push ( Java.lang.Object) Public
boolean java.util.Stack.empty () public
synchronized Java.lang.Object Java.util.Stack.peek () public
synchronized int Java.util.Stack.search (java.lang.Object)

This lists the method names of the Java.util.Stack class and their qualifiers and return types.

This program uses Class.forName to load the specified class and then calls Getdeclaredmethods to get a list of the methods defined in the class. Java.lang.reflect.Methods is a class used to describe a single method in a class.

2. Start using Reflection

Classes used for reflection, such as method, can be found in the Java.lang.relfect package. There are three steps you must follow to use these classes: The first step is to get the Java.lang.Class object of the class you want to manipulate. In a running Java program, use the Java.lang.Class class to describe classes and interfaces.

Here's one way to get a Class object:

Class C = class.forname ("java.lang.String");

This statement gets the class object of a String class. There is another way, such as the following statement:

Class C = int.class; or Class C = integer.type;

They can obtain class information of the basic type. The latter method accesses the predefined type fields in the encapsulated class (such as Integer) of the base types.

The second step is to call a method such as Getdeclaredmethods to get a list of all the methods defined in the class.

Once you get this information, you can take the third step--use the reflection API to manipulate this information, such as the following code:

Class C = class.forname ("java.lang.String"); 
Method m[] = C.getdeclaredmethods (); 
System.out.println (M[0].tostring ()); 

It will print out the prototype of the first method defined in String in a textual way.

In the following example, these three steps provide an example of using reflection to handle special applications.

Analog instanceof operator

After you get the class information, usually the next step is to solve some of the basic questions about the class object. For example, the Class.isinstance method can be used to simulate the instanceof operator:

Class S { 
} public 
class Isinstance {public 
  static void Main (String args[]) { 
   try { 
      class CLS = Class . forname ("S"); 
      Boolean B1 = cls.isinstance (new Integer (Panax)); 
      System.out.println (B1); 
      Boolean b2 = cls.isinstance (New S ()); 
      System.out.println (B2); 
   } 
   catch (Throwable e) { 
      System.err.println (e); 
   } 
  } 
}

In this example, you create a class object of S classes, and then check to see if some objects are instances of S. Integer (37) is not, but new S () is.

3. Find the method of the class

It is a very valuable and very basic reflection usage to find out what methods are defined in a class. The following code implements this usage:

Import java.lang.reflect.*; public class Method1 {private int f1 (Object p, int x) throws NullPointerException {if (p = = null) throw new Nu 
  Llpointerexception (); 
return x; 
      public static void Main (String args[]) {try {Class cls = class.forname ("Method1"); 
      Method methlist[] = Cls.getdeclaredmethods (); 
        for (int i = 0; i < methlist.length. i++) {method M = methlist[i]; 
        System.out.println ("name =" + M.getname ()); 
        System.out.println ("Decl class =" + M.getdeclaringclass ()); 
        Class pvec[] = M.getparametertypes (); 
        for (int j = 0; J < Pvec.length J + +) System.out.println ("param #" + j + "" + pvec[j]); 
        Class evec[] = M.getexceptiontypes (); 
        for (int j = 0; J < Evec.length J + +) System.out.println ("Exc #" + j + "" + evec[j]); 
        System.out.println ("return type =" + M.getreturntype ()); 
      SYSTEM.OUT.PRINTLN ("-----"); }} CATCH (Throwable e) {System.err.println (e);

 } 
  } 
}

The program first obtains a description of the Method1 class, and then calls Getdeclaredmethods to obtain a series of method objects that describe each of the methods defined in the class, including public methods, protected methods, package methods, and Private method and so on. If you use GetMethods in your program instead of Getdeclaredmethods, you can also get information about each method that you inherit.

After you have obtained the list of method objects, it is not difficult to display the parameter types, exception types, and return value types of these methods. Whether these types are basic or class types can be given sequentially by the objects that describe the class.

The results of the output are as follows:

Name = F1 
Decl class = Class method1 
param #0 class java.lang.Object 
param #1 int 
exc #0 class JAVA.LANG.N Ullpointerexception return 
type = int
-----
name = Main 
Decl class = Class method1 
param #0 class [Lja va.lang.String; 
return type = void

4. Get builder Information

The use of the class constructor is similar to that obtained by the above method, such as:

 import java.lang.reflect.*; public class Constructor1 {public Constructor1 () {} prote CTED Constructor1 (int i, double d) {} public static void Main (String args[]) {try {Class CLS = class.f 
      ORName ("Constructor1"); 
      Constructor ctorlist[] = Cls.getdeclaredconstructors (); 
       for (int i = 0; i < ctorlist.length i++) {Constructor ct = ctorlist[i]; 
       System.out.println ("name =" + Ct.getname ()); 
       System.out.println ("Decl class =" + Ct.getdeclaringclass ()); 
       Class pvec[] = Ct.getparametertypes (); 
       for (int j = 0; J < Pvec.length J + +) System.out.println ("param #" + j + "" + pvec[j]); 
       Class evec[] = Ct.getexceptiontypes (); 
       for (int j = 0; J < Evec.length J + +) System.out.println ("Exc #" + j + "" + evec[j]); 
      SYSTEM.OUT.PRINTLN ("-----"); 
   The catch (Throwable e) {System.err.println (e); } 
  } 
}

This example fails to obtain information about the return type because the constructor does not have a return type.

The result of this program running is:

Name = Constructor1
Decl class = Class Constructor1
param #0 int
param #1 Double
-----
name = Construc Tor1
Decl class = class Constructor1
-----

5. Get the field (field) of the class

It's also possible to find out what data fields are defined in a class, and the following code does the same thing:

 import java.lang.reflect.*; 
  public class Field1 {private Double D; 
  public static final int i = 37; 
  String s = "testing"; 
      public static void Main (String args[]) {try {Class cls = class.forname ("Field1"); 
      Field fieldlist[] = Cls.getdeclaredfields (); 
       for (int i = 0; i < fieldlist.length i++) {Field fld = fieldlist[i]; 
       System.out.println ("name =" + Fld.getname ()); 
       System.out.println ("Decl class =" + Fld.getdeclaringclass ()); 
       System.out.println ("type =" + Fld.gettype ()); 
       int mod = Fld.getmodifiers (); 
       System.out.println ("modifiers =" + modifier.tostring (mod)); 
      SYSTEM.OUT.PRINTLN ("-----"); 
   The catch (Throwable e) {System.err.println (e); } 
  } 
}

This example is very similar to the previous example. The example uses a new Modifier, which is also a reflection class that describes the modifiers for a field member, such as "private int". These modifiers themselves are described by integers and use modifier.tostring to return a string description in "official" order (such as "Static" before "final"). The output of this program is:

name = d
Decl class = Class Field1
type = double
modifiers = private
-----
name = i
decl class = C Lass Field1
type = int
modifiers = public static final
-----
name = s
Decl class = Class field1
   
    type = Class java.lang.String
modifiers = 
-----


   

And get the method, you can also get the field information (Getdeclaredfields) that is declared in the current class, or you can get the fields defined in the parent class (GetFields).

6. Execute the method according to the name of the method

The text here, with no exception to the example, is related to how to get the information about the class. We can also use reflection to do other things, such as executing a method that specifies the name. The following example demonstrates this action:

Import java.lang.reflect.*; 
public class Method2 {public 
  int Add (int a, int b) {return 
   a + b; 
  } 
  public static void Main (String args[]) { 
   try { 
      Class cls = Class.forName ("Method2"); 
      Class partypes[] = new class[2]; 
      Partypes[0] = Integer.type; 
      PARTYPES[1] = Integer.type; 
    
      Method meth = Cls.getmethod ("Add", partypes); 
      METHOD2 methobj = new Method2 (); 
      Object arglist[] = new object[2]; 
      Arglist[0] = new Integer (Panax Notoginseng); 
      ARGLIST[1] = new Integer (a); 
      Object retobj = Meth.invoke (Methobj, arglist); 
      Integer retval = (integer) retobj; 
      System.out.println (Retval.intvalue ()); 
   } 
   catch (Throwable e) { 
      System.err.println (e); 
   } 
  } 
}

If a program knows that a method needs to be executed somewhere while it is executing, the name of the method is specified during the run of the program (for example, in a JavaBean development environment), then the above program demonstrates how to do it.

In the example above, GetMethod is used to find a method that has two integer parameters and is named Add. After the method is found and the corresponding methods object is created, it is executed in the correct object instance. When executing this method, you need to provide a list of arguments, in the example above, the two integer objects that are packed with integers 37 and 47, respectively. The return of the execution method is also an Integer object that encapsulates the return value 84.

7. Create a new object

For constructors, it cannot be done as a method, because executing a constructor means creating a new object (exactly, the process of creating an object includes allocating memory and constructing objects). So, the most similar example of the above example is as follows:

Import java.lang.reflect.*; 
public class Constructor2 {public 
  Constructor2 () { 
  } public 
  Constructor2 (int a, int b) { 
   System.out.println ("a =" + A + "b =" + B); 
  } 
  public static void Main (String args[]) { 
   try { 
      Class cls = Class.forName ("Constructor2"); 
      Class partypes[] = new class[2]; 
      Partypes[0] = Integer.type; 
      PARTYPES[1] = Integer.type; 
      Constructor ct = cls.getconstructor (partypes); 
      Object arglist[] = new object[2]; 
      Arglist[0] = new Integer (Panax Notoginseng); 
      ARGLIST[1] = new Integer (a); 
      Object retobj = ct.newinstance (arglist); 
   } 
   catch (Throwable e) { 
      System.err.println (e); 
   } 
  } 
}

Finds the appropriate constructor based on the specified parameter type and executes it to create a new object instance. It is valuable to use this method to dynamically create objects while the program is running, rather than creating objects at compile time.

8. Change the value of a field (field)

Another use of reflection is to change the value of the Object data field. Reflection can find the object's field from the running program based on its name and change it, as the following example illustrates:

Import java.lang.reflect.*; 
public class Field2 {public 
  double D; 
  public static void Main (String args[]) { 
   try { 
      Class cls = Class.forName ("Field2"); 
      Field fld = Cls.getfield ("D"); 
      Field2 f2obj = new Field2 (); 
      System.out.println ("D =" + F2OBJ.D); 
      Fld.setdouble (F2obj, 12.34); 
      System.out.println ("D =" + F2OBJ.D); 
   } 
   catch (Throwable e) { 
      System.err.println (e); 
   } 
  } 
}

In this example, the value of field D is changed to 12.34.

9. Using an array

The last use of the reflection described in this article is an array of operations created. An array is a special class type in the Java language, and a reference to an array can be assigned to an Object reference. Look at the example below to see how the array works:

Import java.lang.reflect.*; 
public class Array1 {public 
  static void Main (String args[]) { 
   try { 
      class CLS = Class.forName ("Java.lang.Stri Ng "); 
      Object arr = array.newinstance (CLS, ten); 
      Array.set (arr, 5, "This is a Test"); 
      string s = (string) array.get (arr, 5); 
      System.out.println (s); 
   } 
   catch (Throwable e) { 
      System.err.println (e); 
   } 
  } 
}

The example creates a 10-unit-length string array, assigns a value to the 5th position string, and then prints the string from the array.

The following code provides a more complex example:

Import java.lang.reflect.*; 
public class Array2 {public 
  static void Main (String args[]) { 
   int dims[] = new Int[]{5; 
   Object arr = array.newinstance (Integer.type, dims); 
   Object arrobj = Array.get (arr, 3); 
   Class cls = Arrobj.getclass (). Getcomponenttype (); 
   SYSTEM.OUT.PRINTLN (CLS); 
   Arrobj = Array.get (Arrobj, 5); 
   Array.setint (Arrobj, Panax Notoginseng); 
   int arrcast[][][] = (int[][][]) arr; 
   System.out.println (arrcast[3][5][10]); 
  } 


The example creates an integer array of 5 x 15 and assigns a value of 37 to the element that is in [3][5][10]. Note that a multidimensional array is actually an array of arrays, for example, after the first array.get, Arrobj is an array of x 15. It then obtains one of the elements, an array of length 15, and assigns a value to its 10th element using Array.setint.

Note that when you create an array, the type is dynamic and does not know its type at compile time .

It is believed that this article has some reference value to everyone's learning of Java programming.

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.