"Programmer" 04, 10th, Trial Read: "Hou Jie View - Java Reflection Mechanism"

xiaoxiao2021-03-06  73

Java reflex mechanism

Summary

Reflection is a key nature of Java as a dynamic (or) language. This mechanism allows the program to get internal information of any known Class of Class, including MODIFIERS (such as public, static, etc.), superclass, such as public, static, etc. Including all information about fields and methods and changes Fields content when runtime or evoke Methods. This article uses examples, large-area demonstration reflection APIs.

About this article:

The reader foundation: with the Java language foundation.

Applicable tools for this article: JDK1.5

Key words:

Introspection (within the province, inner view)

REFLECTION (reflection)

Sometimes we say that a language has strong dynamics, sometimes we will distinguish between dynamics and static different techniques and practices. We Lang Lang's top dynamic binding (Dynamic Linking), dynamic loading, and so on. However, the term "dynamic" does not have absolute and universally applicable strict definitions, sometimes even like object-oriented, like a program, one person, each blow.

In general, the developer community speaks the dynamic language, which is generally recognized by: "When the program is run, the program structure or variable type is allowed, this language is called dynamic language." From this point of view, Perl, Python, Ruby is a dynamic language, C , Java, C # is not a dynamic language.

Despite this definition and classification Java is not a dynamic language, it has a very prominent dynamic related mechanism: reflection. This word means "reflection, image, reflection", refers to the Java, which we can load, detect, complete unknown Classes during the compilation period. In other words, the Java program can load a Class of the name to know the name of the name, knowing its integrity (but not included), and generates its object entity, or sets the Fields, or evokes its Methods1. This "The Ability of the Program" Itself) is called Introspection (within the province, inner view, reflection). Reflection and Introspections are often used in two terms.

How can Java make the above dynamic characteristics? This is a profound topic, this article is only briefly introduced some concepts. The whole parameter is the most important to introduce the Reflection APIS, which is to let the reader know how to explore the structure of the class, how to generate a entity for a "Class" Class ", set the value, and call it Methods. This article will talk about java.lang.class, as well as the Method, Field, Constructors, etc. in Java.lang.Reflect, etc. Classes.

Class "Class

It is well known that Java has an Object Class, which is the inheritance of all Java Classes, which declares several Methods: hashcode (): hashcode (), equals: hashcode (): hashcode (), Equals (), Clone (), Tostring (), getClass )Wait. Where getClass () returns a Class Object. Class Class is very special. It is inherited from Object as a general class, which is actually used to express Classes and Interfaces at the Java program, also used to express Enum, Array, Primitive Java Types (Boolean, Byte, Char, Short, Int, Long, Float, Double ) And keyword void. When a Class is loaded, or when the debcon is called by the JVM, the JVM automatically generates a Class Object. If you want to observe the actual generation timing of Class Object by "Modify Java Standard Library Source Code" (for example, add a println () in the CLASS CONSTRUctor), can not! Because Class is not public constructor (see Figure 1). In this article, I will allocate a small piece of space to talk about the change of Java standard library source code.

Class is the origin of Reflection story. For any Class you want to explore, only one Class Object is produced first, and then you can evoke to dozens of Reflection APIs via the latter. These APIs will be unveiled in a later expedition.

# 001 Public Final

# 002 Class Class Implements java.io.serializable,

# 003 java.lang.reflect.GenericDeclaration,

# 004 java.lang.reflect.Type,

# 005 java.lang.reflect.annotatedElement {

# 006 private class () {}

# 007 public string toString () {

# 008 RETURN (Isinterface ()? "Interface":

# 009 (isprimitive ()? ":" Class "))

# 010 getname ();

# 011}

...

Figure 1: Class Class clip. Note Its Private Empty CTOR means that anyone does not allow anyone to generate Class Object via programming. Yes, its Object can only be generated by JVM.

"Class" Object's Getting Ways

Java allows us to generate corresponding Class Object from a variety of pipes. Figure 2 is a sorting.

Class Object Nativity Pipeline

Example

Apply getClass ()

Note: Every Class has this function

String str = "abc";

Class C1 = str.getClass ();

use

Class.getsuperClass () 2

Button b = new button ();

Class C1 = B.GetClass ();

Class C2 = c1.getsuperclass ();

Apply Static Method

Class.Forname ()

(Most often used)

Class C1 = Class.Forname ("java.lang.string"); Class C2 = Class.Forname ("java.awt.button);

Class C3 = Class.Forname ("java.util.linkedList $ entry");

Class C4 = Class.Forname ("i");

Class C5 = Class.Forname ("[i");

use

.class syntax

Class C1 = String.class;

Class C2 = java.awt.button.class;

Class C3 = main.innerclass.class;

Class C4 = Int.class;

Class C5 = Int []. Class;

use

Primitive Wrapper Classes

Type syntax

Class C1 = Boolean.Type;

Class C2 = byte.Type;

Class C3 = Character.Type;

Class C4 = short.type;

Class C5 = Integer.Type;

Class C6 = long.Type;

Class C7 = float.Type;

Class C8 = Double.Type;

Class C9 = void.type;

Figure 2: Java allows multiple pipes to generate Class Object.

Java classes composition analysis

First, I will take the java.util.linkedList of Figure 3 as an example, and the definition of Java Class is unloaded, each piece corresponding to the Reflection API shown in FIG. 4. Figure 5 is a program example and execution result of obtaining Class Each block information, each of which takes a corresponding segment from the sample program.

Package java.util; // (1)

Import java.lang. *; // (2)

Public Class LinkedList // (3) (4) (5)

Extends AbstractSequentialList // (6)

Implements list , queue ,

Cloneable, java.io.serializable // (7)

{

Private static class entry {...} // (8)

Public LinkedList () {...} // (9)

Public LinkedList (Collection c) {...}

Public e getFirst () {...} // (10)

Public E getLast () {...}

Private transient entry header = ...; // (11)

Private transient int size = 0;

}

Figure 3: Eight blocks a Java Class, each of which corresponds to one or a set of REFLECTION APIs (Figure 4).

REFLECTION APIS corresponding to Java Classes

The respective Java Class components of Figure 3 correspond to the Reflection API of Figure 4, which appears in Package, Method, Constructor, Field, etc., is defined in java.lang.reflect. Java Class internal module (see Figure 3)

Java Class internal module description

The corresponding reflection API, mostly Class methods.

Return value type (RETURN TYPE)

(1) Package

Which package is affiliated with CLASS

GetPackage ()

Package

(2) Import

Class import which classes

There is no directly corresponding to the API.

Solution is shown in Figure 5-2.

(3) MODIFIER

Attributes of Class (or Methods, Fields)

Int getModifiers ()

Modifier.toString (int)

Modifier.isInterface (int)

int

String

Bool

(4) Class name or interface name

Class / Interface

Name getName ()

String

(5) Type Parameters

Name of parameterization

GettypeParameters ()

TYPEVARIABLE []

(6) Base Class

Base Class (only one)

GetSuperClass ()

Class

(7) Implement Interfaces

What Intelligence is implemented

GetInterfaces ()

Class []

(8) Inner Classes

Interior Classes

GetDeclaredClasses ()

Class []

(8 ') Outer Class

If we observe the Class itself is inner classes, there will be an Outer Class relative to it.

getDeclaringclass ()

Class

(9) Constructors

Constructor getDeclaredConstructors ()

Regardless of public or private or other Access Level, it is available. Another function of approximation.

Constructor []

(10) Methods

Operation function getDeclaredMethods ()

Regardless of public or private or other Access Level, it is available. Another function of approximation.

Method []

(11) Fields

Field (member variable)

GetDeclaredFields () is available regardless of public or private or other Access Level. Another function of approximation.

Field []

Figure 4: Java Class is unloaded (as shown in Figure 3), and the REFLECTION API corresponding to each piece. This table is not

All of the Reflection APIS.

Java Reflection API Application Example

Figure 5 shows each Reflection API, and its execution results. The TNAME () that appears in the program is an auxiliary function that strips the "Java Class full path string" represented by its first argument to the path portion, leaving a Class name, saved to a HashTable represented by the second argument. Go and return (if the second index is null, it is not stored but only returns).

# 001 Class C = NULL;

#

002 C

= Class.Forname (Args [0]);

# 003

# 004 package p; # 005 p = c.getPackage ();

# 006

# 007 if (p! = Null)

# 008 System.out.println ("Package" P.GetName () ";");

Execution (Example):

Package java.util;

Figure 5-1: Find the package membership. The C will continue to be used in the following segments.

# 001 ff = c.getdeclaredfields ();

# 002 for (INT i = 0; i

# 003 x = TNAME (ff [i] .gettype (). GetName (), ClassRef;

# 004

# 005 cn = c.getDeclaredConstructors ();

# 006 for (INT i = 0; i

# 007 Class CX [] = CN [i] .GetParameterTypes ();

# 008 for (int J = 0; j

# 009 x = TNAME (CX [J] .getName (), ClassRef;

# 010}

# 011

#

012 mm

= c.getDeclaredMethods ();

# 013 for (INT i = 0; i

# 014 x = TNAME (mm [i] .getreturntype (). GetName (), ClassRef;

# 015 Class CX [] = mm [i] .GetparameterTypes ();

# 016 for (int J = 0; j

# 017 x = TNAME (CX [J] .getName (), ClassRef;

# 018}

# 019 ClassRef.remove (c.getname ()); // Don't record yourself (don't need import yourself)

Execution (Example):

Import java.util.listiterator;

Import java.lang.object;

Import java.util.linkedList $ entry;

Import java.util.collection;

Import java.io.ObjectOutputStream;

Import java.io.objectInputstream;

Figure 5-2: Finding the imported classes, the details of the action details are detailed in terms of instructions.

# 001 INT MOD = C.getModifier ();

# 002 System.out.Print (Modifier.Tostring (MOD)); // Whole Modifier

# 003

# 004 IF (Modifier.isInterface (MOD))

# 005 system.out.print (""); // Keyword "interface" has included in Modifier

# 006 else

# 007 System.out.Print ("Class"); // Keyword "Class"

# 008 System.out.print (TName (c.getname (), null); // Class name execution result (Example):

Public class linkedList

Figure 5-3: Find the name of the Class or Interface, and its properties (Modifier).

# 001 TYPEVARIABLE [] TV;

# 002 TV = c.gettypeParameters (); // Warning: unchecked conversion

# 003 for (INT i = 0; i

# 004 x = TNAME (TV [i] .getname (), null); //, for example E, K, V ...

# 005 IF (i == 0) // First

# 006 System.out.print ("<" x);

# 007 Else // Non-first

# 008 System.out.print ("," x);

# 009 if (i == tv.length-1) // last one

# 010 system.out.println (">");

# 011}

Execution (Example):

Public Abstract Interface Map

Or Public Class LinkedList

Figure 5-4: Find the name of Parameterized Types

# 001 Class SupClass;

# 002 supclass = c.getusuperclass ();

# 003 IF (supclass! = Null) // If there is a super class

# 004 System.out.print ("extends"

# 005 TNAME (SupClass.getName (), ClassRef);

Execution (Example):

Public Class LinkedList

Extends AbstractSequentialList,

Figure 5-5: Find the base class. Executive results have an additional comma on the tail. This is not focusing on the part, for simplicity, not much processing.

# 001 Class CC [];

# 002 Class CTMP;

# 003 // Find all implemented Interfaces

# 004 cc = c.getInterfaces ();

# 005 IF (cc.length! = 0)

# 006 System.out.Print (", / R / N" "Implements"); // Keywords

# 007 for (Class Cite: Cite: CC) //JDK1.5 New Cycle Writing

# 008 System.Out.print (TName (Cite.getName (), NULL) ",");

Execution (Example):

Public Class LinkedList

Extends AbstractSequentialList,

Implements List, Queue, Cloneable, Serializable,

Figure 5-6: Finding the Implement Interfaces. Executive results have an additional comma on the tail. This is not focusing on the part, for simplicity, not much processing. # 001 cc = c.getDeclaredClasses (); // Find inner classes

# 002 for (Class Cite: CC)

# 003 System.out.Println (TName (Cite.getName (), NULL);

# 004

# 005 CTMP = C.getDeclaringClass (); // to find out Outer Classes

# 006 if (CTMP! = NULL)

# 007 System.out.println (CTMP.GetName ());

Execution (Example):

LinkedList $ Entry

LinkedList $ LISTITRRRRR

Figure 5-7: Finding Inner Classes and Outer Class

# 001 CONSTRUctor CN [];

# 002 CN = C.getDeclaredConstructors ();

# 003 for (int i = 0; i

# 004 INT MD = CN [i] .getmodifiers ();

# 005 System.out.print ("" Modifier.Tostring (MD) " "

# 006 CN [i] .getname ());

# 007 Class CX [] = CN [i] .GetParameterTypes ();

# 008 System.out.print (");

# 009 for (int J = 0; j

# 010 System.out.print (TNAME (CX [J] .getname (), NULL);

# 011 i (j <(cx.length - 1)) system.out.print (",");

# 012}

# 013 system.out.print (")");

# 014}

Execution (Example):

Public Java.util.LINKEDLIST (Collection)

Public Java.util.LinkedList ()

Figure 5

-8a

: Find all constructors

# 004 System.out.println (CN [i] .togenericstring ());

Execution (Example):

Public Java.util.LINKEDLIST (Java.util.collection )

Public Java.util.LinkedList ()

Figure 5-8b: Find all constructors. This example uses toGenericstring (), provincial things in the For cycle.

# 001 Method mm [];

#

002 mm

= c.getDeclaredMethods ();

# 003 for (INT i = 0; i

# 004 INT MD = mm [i] .getmodifiers ();

# 005 System.out.print (" Modifier.Tostring (MD) " " # 006 TNAME (mm [i] .getreturntype (). Getname (), null) " "

#

007

MM [i] .getname ());

# 008 Class CX [] = mm [i] .GetParameterTypes ();

# 009 System.out.print (");

# 010 for (int J = 0; j

# 011 System.out.print (TNAME (CX [J] .getname (), NULL);

# 012 IF (j <(cx.length - 1)) system.out.print (",");

# 013}

# 014 system.out.print (")");

# 015}

Execution (Example):

Public Object Get (int)

Public int size ()

Figure 5

-9a

: Find all Methods

# 004 System.out.println (mm [i] .togenericstring ());

Public e java.util.LinkedList.Get (int)

Public int java.util.LinkedList.size ()

Figure 5-9B: Find all Methods. This example uses toGenericstring (), provincial things in the For cycle.

# 001 Field FF [];

# 002 ff = c.getDeclaredfields ();

# 003 for (INT i = 0; i

# 004 INT MD = ff [i] .getmodifiers ();

# 005 System.out.println ("" Modifier.toString (MD) " "

# 006 TNAME (ff [i] .gettype (). Getname (), null) "" "

# 007 ff [i] .getname () ";");

# 008}

Execution (Example):

Private Transient LINKEDLIST $ Entry HEADER;

Private transient int size;

Figure 5

-10A

: Find all of Fields

# 004 System.out.println ("g:" ff [i] .togenericstring ());

Private transient java.util.linkedList.java.util.LINKEDLIST $ Entry ??

Java.util.LINKEDLIST.HEADER

Private transient int java.util.linkedList.Size

Figure 5-10B: Find all of the Fields. This example uses toGenericstring (), provincial things in the For cycle.

Find all ClassSes for Class access (import)

The Reflection API that is not available directly can find all other Classes for a CLASS reference. To get this information, you must work hard, one step by one footprint. We must observe all Fields types, all Methods (including constructors) parameter types and return types, rejection repeat, leaving unique. This is why Figure 5-2 Program code To specify a HashTable (not a null) as a second self-variable for TNAME (): Hashtable can store the element (this example is a string), but not repeat. This article discusses that, almost restores the original appearance of a Class (only the definition of Methods and CTORs cannot be obtained). Next discussion of the other three dynamic properties of Reflection: (1) Generate instances, (2)

The period evokes Methods, (3) Change Fields when running.

Generate instances at runtime

To generate an object entity, there are two practices in the Reflection dynamic mechanism, one for "no self-variable CTOR",

A for the "Parameter CTOR". Figure 6 is an example of facing "no self-variable CTOR". If you want to call the "Parameter CTOR", it is more troublesome, Figure 7 is an example, where the Class's newInstance () is no longer invoking the constructor's newInstance (). Figure 7 first prepares a class [] as a parameter type of CTOR (this example is specified as a double and an int), then call GetConstructor () as the argument to get a dedicated CTOR. Next, you will prepare an object [] as a CTOR implementation (this example 3.14159 and 125), call the above-mentioned exclusive CTOR's newInstance ().

# 001 Class C = Class.Forname ("DYNTEST");

# 002 Object obj = null;

# 003 obj = c.newinstance (); // without argument

# 004 System.out.println (OBJ);

Figure 6: Dynamically generates object entities of "Class Object"; no argument.

# 001 Class C = Class.Forname ("DYNTEST");

# 002 Class [] ptypes = new class [] {double.class, int.class};

# 003 constructor ctor = c.getconstructor (ptypes);

# 004 // Specify parameter List to get a specific CTOR

# 005

# 006 Object Obj = NULL;

# 007 Object [] arg = new object [] {3.14159, 125}; // argument

# 008 Obj = Ctor.newinStance (arg);

# 009 System.out.println (OBJ);

Figure 7: Dynamically generates object entities of "Class Object Class"; independent variables are represented by Object [].

Call Methods at runtime

This action is quite similar to the above-described call "CTOR" with parameters. First prepare a class [] as a CTOR parameter type (this example specifies one of these is String, the other is HashTable), then call GetMethod (), get a specific Method Object. Next, an Object [] places an argument, then call the Invoke () of the specific Method Object described above, as shown in Figure 8. Know why you don't need to specify a return type when requesting Method Object? Because the Method OverLoading mechanism requires Signature (signed) must be unique, the return type is not a component of Signature. In other words, as long as the Method name and parameter column are specified, it must be pointed out in a unique Method. # 001 Public String Func (String S, HashTable HT)

# 002 {

# 003 ... System.out.println ("Func Invoked"); Return S;

# 004}

# 005 public static void main (string args [])

# 006 {

# 007 Class C = Class.Forname ("Test");

# 008 Class Ptypes [] = new class [2];

# 009 ptypes [0] = Class.Forname ("java.lang.string");

# 010 ptypes [1] = Class.Forname ("java.util.hashtable);

# 011 Method M = C.getMethod ("FUNC", PTYPES);

# 012 Test obj = new test ();

# 013 Object args [] = new object [2];

# 014 arg [0] = New string ("Hello, World");

# 015 arg [1] = NULL;

# 016 Object R = M.Invoke (OBJ, ARG);

# 017 integer rval = (string) r;

# 018 System.out.println (RVAL);

# 019}

Figure 8: Dynamic Method Method

Change Fields content at runtime

Compared with the previous two actions, "Change Field Content" is relaxed because it does not require parameters and arguments. First call the Class's getField () and specify the Field name. After getting specific Field Object, you can directly call GET () and set (), as shown in Figure 9.

# 001 public class test {

# 002 public double d;

# 003

# 004 public static void main (string args [])

# 005 {

# 006 Class C = Class.Forname ("Test");

# 007 FIELD F = C.Getfield ("D"); // Specify the Field Name

# 008 Test obj = new test ();

# 009 System.out.println ("D =" (Double) F.Get (OBJ));

#

010

fly

.SET (OBJ, 12.34);

# 011 system.out.println ("d =" Obj.d);

# 012}

# 013}

Figure 9: Dynamic Change Field Content Java Source Code Change Measures

I mentioned before, I originally wanted to use the "Change Java Standard Library Source Code" to identify the generation of Class Object, but because of its CTOR original design as Private, that is, it is impossible to generate Class Object through this pipe (but by Class Loader is responsible for generating), so attempts to "print some kind of information in CTOR" will lose its meaning.

Here I am going to talk out: How to modify the Java standard library source code and let it react to our application. Suppose I want to modify java.lang.class, let it print some kind of information in some cases. First, you must find the standard source code! When you download the JDK kit and install it, you will find Class.java in the JDK150 / SRC / Java / LANG directory (see Figure 10), which is the standard source code for our actions. After backup, modify it, compile to Class.Class. Next, you will be prepared to move .CLASS to JDK150 / JRE / LIB / ENDORSED (see Figure 10).

This is a very special directory, Class Loader will prioritize Classes-containing .jar files - successful conditions are. Jar's Classes compression paths must be exactly the same as the Java standard library. To this end, we can move the class.class just now move to a / java / lang directory that deliberately made for this purpose, compresses to foo.zip (any name, virtual entrained path java / lang), The foo.zip moved to JDK150 / JRE / lib / endorsed and renamed to foo.jar. Since then your application will give priority to java.lang.class here. The entire process can be written into a batch file, as shown in Figure 11, in DOS BOX.

Figure 10: Directory organization after JDK1.5. Where endorsed is my new.

Del E: / java / lang / *. Class // Clean up clean

Del c: /jdk150/jre/lib/endorsed/foo.jar // Clean clean

C:

CD C: / JDK150 / SRC / JAVA / LANG

Javac-xlint: unchecked class.java // Compile source code

Javac-xlint: unchecked classloader.java // Compile another source code (if necessary)

Move * .class e: / java / lang // Moved to deliberately manufactured directories

E:

CD E: / java / lang // below to compress to the appropriate directory

PKZIPC -ADD -PATH = root c: /jdk150/jre/lib/endorsed/foo.jar * .class

CD E: / Test // Enter the test directory

Javac-xlint: unchecked test.java // Compiling Test Programs

Java Test // Execute Test Programs

Figure 11: A batch file that can be used in DOS BOX to automate java.lang.class

Modifying action. PKZIPC (.exe) is a command column compression tool, add and path are their commands.

More information

The following is more discussions related to the field of view and this theme of this article. This information makes up for the shortcomings of the article constraints, or bring you more vision.

l "Take An In-Depth Look At The Java Reflection API - Learn About The New Java 1.1 Tools forfinding Out Information About Classes", by Chuck Mcmanis. This article apart code is the main basis for this example program (this sample program demonstrates more reflection APIs, and uses JDK1.5 new For-loop Writing). L "Take a Look Inside Java Classes - Learn to Deduce PROPERTIES OF A Java Class from Inside Ajava Program", by Chuck Mcmanis.

l "The Basics of Java Class Loaders - The Fundamentals of this Key Component of the JavaarchIture, by Chuck Mcmanis.

l "The Java Tutorial Continue, Sun Microsystems. Lesson58-61," Reflection ".

Note 1 Programmer who has used such a so-called Application Framework such as MFC may know that MFC has a so-called Dynamic Creation. But it does not equivalent to dynamic loading or dynamic identification of Java; all Classes that can play in the MFC program must first be "see" in the compiler.

Note 2 If the operation object is Object, class.getsuperclass () will return NULL.

This article is available to the Houjie website.

http://www.jjhou.com/javatwo-2004-reflection-and-generics-in-jdk15-sample.zip

转载请注明原文地址:https://www.9cbs.com/read-92532.html

New Post(0)