Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Rolle der Java-Reflexion

Detaillierte Erläuterung der Rolle der Java-Reflexion

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

Der Reflexionsmechanismus von Java ist eines der Merkmale von Java, und der Reflexionsmechanismus ist die Grundlage für die Entwicklung der Framework-Technologie. Die flexible Beherrschung des Java-Reflexionsmechanismus wird in Zukunft für alle beim Erlernen der Framework-Technologie eine große Hilfe sein.

Was ist also Reflexion in Java?

Jeder weiß, dass die Java-Klasse von der Java Virtual Machine geladen werden muss, damit ein Java-Programm ausgeführt werden kann. Java-Klassen können nicht normal ausgeführt werden, wenn sie nicht von der Java Virtual Machine geladen werden. Jetzt wissen alle von uns ausgeführten Programme, dass die von Ihnen benötigte Klasse während der Kompilierung geladen wurde.

Der Reflexionsmechanismus von Java besteht darin, dass es nicht bestimmt, welche Klasse während der Kompilierung geladen wird, sondern sie nur lädt, erkennt und selbst prüft, wenn das Programm geladen wird läuft. Verwenden Sie Klassen, die zur Kompilierungszeit nicht bekannt sind. Ein solches Merkmal ist Reflexion.

Was macht also die Java-Reflektion?

Angenommen, wir haben zwei Programmierer, wenn ein Programmierer ein Programm schreibt, muss er die vom zweiten Programmierer geschriebene Klasse verwenden, aber der zweite Programmierer hat die Klasse nicht abgeschlossen er schrieb. Kann also der Code des ersten Programmierers kompiliert werden? Dies kann nicht kompiliert werden. Mithilfe des Java-Reflexionsmechanismus kann der erste Programmierer die Kompilierung seines eigenen Codes abschließen, ohne dass der zweite Programmierer die Klasse schreiben muss.

Javas Reflexionsmechanismus kennt die Grundstruktur der Klasse. Diese Fähigkeit, die Klassenstruktur von Java zu erkennen, wird „Selbstüberprüfung“ von Java-Klassen. Jeder hat Jcreator und Eclipse verwendet. Wenn wir ein Objekt konstruieren, rufen wir die Methoden und Eigenschaften des Objekts auf. Mit einem Klick listet das Kompilierungstool automatisch alle Methoden und Eigenschaften auf, die vom Objekt verwendet werden können, damit der Benutzer sie auswählen kann. Dabei wird das Prinzip der Java-Reflexion genutzt, um die von uns erstellten Objekte zu erkennen und selbst zu untersuchen.

Klassenklasse

Zur Verwendung des Java-Reflexionsmechanismus richtig Sie müssen die Klasse java.lang.Class verwenden. Es ist der Ursprung des Java-Reflexionsmechanismus. Wenn eine Klasse geladen wird, generiert die Java Virtual Machine automatisch ein Klassenobjekt. Über dieses Klassenobjekt können wir Informationen wie die Deklaration und Definition der Methoden, Mitglieder und Konstruktoren erhalten, die dem in die virtuelle Maschine geladenen Klassenobjekt entsprechen.

Reflection API

Wird verwendet, um die Klassen-, Schnittstellen- oder Objektinformationen im aktuellen Java Virtual wiederzugeben Maschine u

Funktion

– Klasseninformationen eines Objekts abrufen.
– Zugriffsmodifikatoren, Mitglieder, Methoden, Konstruktoren und Superklasseninformationen einer Klasse abrufen.

– Ruft Konstanten- und Methodendeklarationen ab, die zu einer Schnittstelle gehören .

– Erstellt eine Schnittstelle, deren Name erst bekannt ist, wenn das Programm ausgeführt wird.

– Mitglieder eines Objekts abrufen und festlegen, und sogar der Name dieses Mitglieds ist nur während der Ausführung des Programms bekannt.


– Methode zum Erkennen eines Objekts, dessen Name nur zur Laufzeit bekannt ist

Mithilfe des Java-Reflektionsmechanismus können wir Klasseninformationen, die in die virtuelle Java-Umgebung geladen wurden, einfach und flexibel erkennen Maschine. Natürlich wird diese Art der Erkennung die Leistung des Betriebs schwächen, daher hängt der Zeitpunkt der Verwendung von Reflektion von den Anforderungen, der Größe des Unternehmens und der gesammelten Erfahrung ab.

Wie nutzen Sie also die Reflection-API, um die Informationen einer Klasse zur Laufzeit zu erfahren?

Codebeispiel:

Beim Ausführen geben wir javax.swing.JFrame ein, dann ist das Laufergebnis wie folgt:

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();
    }
}
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这个类的一个对象。 

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Rolle der Java-Reflexion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn