Home  >  Article  >  Java  >  Detailed explanation of the role of Java reflection

Detailed explanation of the role of Java reflection

PHP中文网
PHP中文网Original
2017-06-22 14:20:20989browse

Java's reflection mechanism is one of Java's features, and the reflection mechanism is the basis for building framework technology. Flexibly mastering the Java reflection mechanism will be of great help to everyone in learning framework technology in the future.

So what is reflection in Java?

We all know that in order for a Java program to run, the Java class must be loaded by the Java virtual machine. Java classes cannot run normally if they are not loaded by the Java virtual machine. Now all the programs we run know that the class you need has been loaded during compilation.

#The reflection mechanism of Java is that it does not determine which class is loaded during compilation, but only loads, detects, and self-examines it when the program is running. Use classes that are not known at compile time. Such a feature is reflection.

So what does Java reflection do?

Suppose we have two programmers. When one programmer writes a program, he needs to use the class written by the second programmer, but the second programmer Didn't finish the class he wrote. So can the first programmer's code compile? This cannot be compiled. Using the Java reflection mechanism, the first programmer can complete the compilation of his own code without getting the class written by the second programmer.

Java's reflection mechanism knows the basic structure of the class. This ability to detect the Java class structure is called Java "Self-examination" of classes. Everyone has used Jcreator and eclipse. When we construct an object, we call the methods and properties of the object. With one click, the compilation tool will automatically list all the methods and properties that can be used by the object for the user to choose. This uses the principle of Java reflection to detect and self-examine the objects we create.

Class class

##                                            To use the Java reflection mechanism correctly You have to use the java.lang.Class class. It is the origin of Java reflection mechanism. When a class is loaded, the Java virtual machine will automatically generate a Class object. Through this Class object, we can obtain information such as the declaration and definition of the methods, members, and constructors corresponding to the Class object loaded into the virtual machine.

Reflection API

##           uReflection API Used to reflect the class, interface or object information in the current Java virtual machine

uFunction—Get an object’s Class information.

—Get access modifiers, members, methods, constructors and superclass information of a class.

## —The constant and method declaration that belongs to an interface.

## —— Create a name that did not know the name until the program was running. Instances of classes.

 —Get and set members of an object, even the name of this member is

only known during the running of the program.


 —Method to detect an object whose name is known only during runtime

##             we can easily Flexibly detect class information that has been loaded into the Java virtual machine. Of course, this kind of detection will weaken the performance of the operation, so when to use reflection depends on the needs, size of the business, and the accumulation of experience.

So how do you use the reflection API to know the information of a class at runtime?

Code example:

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
/**
  *本类用于测试反射API,利用用户输入类的全路径,
*找到该类所有的成员方法和成员属性
  */
public class MyTest {
     /**
     *构造方法
     */
    public MyTest(){
       String classInfo=JOptionPane.showInputDialog(null,"输入类全路径");//要求用户输入类的全路径
       try {
           Class cla=Class.forName(classInfo);//根据类的全路径进行类加载,返回该类的Class对象
          
           Method[] method=cla.getDeclaredMethods();//利用得到的Class对象的自审,返回方法对象集合
          
           for(Method me:method){//遍历该类方法的集合
              System.out.println(me.toString());//打印方法信息
           }
          
           System.out.println("********");
          
           Field[] field=cla.getDeclaredFields();//利用得到的Class对象的自审,返回属性对象集合
           for(Field me:field){ //遍历该类属性的集合
              System.out.println(me.toString());//打印属性信息
           }
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
    }
    public static void main(String[] args) {
       new MyTest();
    }
}

When running, we enter javax.swing.JFrame, then the running results are as follows:

public void javax.swing.JFrame.remove(java.awt.Component)

public void javax.swing.JFrame.update(java.awt.Graphics )

…………

********

public static final int javax.swing.JFrame.EXIT_ON_CLOSE

private int javax.swing.JFrame.defaultCloseOperation

…………

    大家可以发现,类的全路径是在程序运行的时候,由用户输入的。所以虚拟机事先并不知道所要加载类的信息,这就是利用反射机制来对用户输入的类全路径来对类自身的一个自审。从而探知该类所拥有的方法和属性。

通过上面代码,大家可以知道编译工具为什么能够一按点就能列出用户当前对象的属性和方法了。它是先获得用户输入对象的字符串,然后利用反射原理来对这样的类进行自审,从而列出该类的方法和属性。

使用反射机制的步骤:

u导入java.lang.relfect 包

u遵循三个步骤
第一步是获得你想操作的类的 java.lang.Class 对象
第二步是调用诸如 getDeclaredMethods 的方法
第三步使用 反射API 来操作这些信息

获得Class对象的方法

u如果一个类的实例已经得到,你可以使用

       【Class c = 对象名.getClass(); 

      例: TextField t = new TextField();

              Class c = t.getClass();

              Class s = c.getSuperclass();

u如果你在编译期知道类的名字,你可以使用如下的方法

Class c = java.awt.Button.class; 
或者

         Class c = Integer.TYPE;

u如果类名在编译期不知道, 但是在运行期可以获得, 你可以使用下面的方法

          Class c = Class.forName(strg);

   这样获得Class类对象的方法,其实是利用反射API把指定字符串的类加载到内存中,所以也叫类加载器加载方法。这样的话,它会把该类的静态方法和静态属性,以及静态代码全部加载到内存中。但这时候,对象还没有产生。所以为什么静态方法不能访问非静态属性和方法。因为静态方法和属性产生的时机在非静态属性和方法之前。

代码示例:

package  com;
 
public class MyTest {
    public static void main(String[] args) {
       TestOne  one=null;
       try{
       Class  cla=Class.forName("com.TestOne");//进行com.TestOne类加载,返回一个Class对象
       System.out.println("********");
       one=(TestOne)cla.newInstance();//产生这个Class类对象的一个实例,调用该类无参的构造方法,作用等同于new TestOne()
       }catch(Exception e){
           e.printStackTrace();
       }
       TestOne two=new TestOne();
  System.out.println(one.getClass() == two.getClass());//比较两个TestOne对象的Class对象是否是同一个对象,在这里结果是true。说明如果两个对象的类型相同,那么它们会有相同的Class对象
    }
}
 
class TestOne{
    static{
       System.out.println("静态代码块运行");
    }
    TestOne(){
       System.out.println("构造方法");
    }
}

  以上代码过行的结果是:

静态代码块运行

***********

构造方法

构造方法


代码分析:

在进行Class.forName("com.TestOne")的时候,实际上是对com.TestOne进行类加载,这时候,会把静态属性、方法以及静态代码块都加载到内存中。所以这时候会打印出"静态代码块运行"。但这时候,对象却还没有产生。所以"构造方法"这几个字不会打印。当执行cla.newInstance()的时候,就是利用反射机制将Class对象生成一个该类的一个实例。这时候对象就产生了。所以打印"构造方法"。当执行到TestOne two=new TestOne()语句时,又生成了一个对象。但这时候类已经加载完毕,静态的东西已经加载到内存中,而静态代码块只执行一次,所以不用再去加载类,所以只会打印"构造方法",而"静态代码块运行"不会打印。

反射机制不但可以例出该类对象所拥有的方法和属性,还可以获得该类的构造方法及通过构造方法获得实例。也可以动态的调用这个实例的成员方法。

代码示例:

package reflect;
 
import java.lang.reflect.Constructor;
 
 
/**
 *
 * 本类测试反射获得类的构造器对象,
 * 并通过类构造器对象生成该类的实例
 *
 */
public class ConstructorTest {
 
    public static void main(String[] args) {
       try {
           //获得指定字符串类对象
           Class cla=Class.forName("reflect.Tests");
           //设置Class对象数组,用于指定构造方法类型
           Class[] cl=new Class[]{int.class,int.class};
          
           //获得Constructor构造器对象。并指定构造方法类型
           Constructor con=cla.getConstructor(cl);
          
           //给传入参数赋初值
           Object[] x={new Integer(33),new Integer(67)};
          
           //得到实例
           Object obj=con.newInstance(x);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
 
}
 
class Tests{
    public Tests(int x,int y){
       System.out.println(x+"    "+y);
    }
}

运行的结果是” 33    67。说明我们已经生成了Tests这个类的一个对象。 

The above is the detailed content of Detailed explanation of the role of Java reflection. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn