ホームページ Java &#&チュートリアル Javaリフレクションの役割の詳しい説明

Javaリフレクションの役割の詳しい説明

Jun 22, 2017 pm 02:20 PM
class java 仮想マシン

Java のリフレクション メカニズムは Java の機能の 1 つであり、リフレクション メカニズムはフレームワーク技術を構築するための基礎です。 Java のリフレクション メカニズムを柔軟に使いこなすことは、将来フレームワーク テクノロジを学習する際に大きな助けとなるでしょう。

では、Java におけるリフレクションとは何でしょうか?

Java プログラムを実行するには、Java クラスが Java 仮想マシンによってロードされる必要があることは誰もが知っています。 Java クラスは、Java 仮想マシンによってロードされないと正常に実行できません。これで、実行するすべてのプログラムは、必要なクラスがコンパイル中にロードされたことを認識します。

Java のリフレクション メカニズムでは、コンパイル中にどのクラスがロードされるかは決定されず、プログラムの実行時にのみロード、検出、自己検査が行われます。コンパイル時に不明なクラスを使用します。そのような機能が反射です。

では、Java リフレクションは何をするのでしょうか?

プログラマが 2 人いるとします。1 人のプログラマがプログラムを作成するとき、2 人目のプログラマが作成したクラスを使用する必要がありますが、2 人目のプログラマは自分が作成したクラスを完了していません。では、最初のプログラマーのコードはコンパイルできるでしょうか?これはコンパイルできません。 Java リフレクション メカニズムを使用すると、最初のプログラマは、2 番目のプログラマにクラスを作成してもらうことなく、自分のコードのコンパイルを完了できます。

Javaのリフレクションメカニズムは、クラスの基本構造を知っています。このJavaのクラス構造を検出する機能は、Javaクラスの「自己検査」と呼ばれます。誰もが Jcreator と Eclipse を使用したことがあります。オブジェクトを構築するときは、オブジェクトのメソッドとプロパティを呼び出します。ワンクリックで、コンパイル ツールはオブジェクトで使用できるすべてのメソッドとプロパティを自動的にリストし、ユーザーが選択できるようにします。これは、Java リフレクションの原理を使用して、作成したオブジェクトを検出し、自己検査します。

Class クラス

は正しく使用する必要があります

java 反射メカニズムでは、java.lang.class のクラスを使用する必要があります。これは、Java のリフレクション メカニズムの起源です。クラスがロードされると、Java 仮想マシンは Class オブジェクトを自動的に生成します。この Class オブジェクトを通じて、仮想マシンにロードされた Class オブジェクトに対応するメソッド、メンバー、コンストラクターの宣言と定義などの情報を取得できます。 Reflection API

uReflection APIは、現在のJava仮想マシンのクラス、インターフェース、またはオブジェクトの情報を反映するために使用されます u

関数—取得one オブジェクトのクラス情報
- クラスのアクセス修飾子、メンバー、メソッド、コンストラクター、およびスーパークラス情報を取得します

- インターフェイスに属する定数とメソッド宣言を取得します。

— プログラムが実行されるまで名前が不明なクラスのインスタンスを作成します。

— メンバーの名前が である場合でも、オブジェクトのメンバーを取得および設定します。プログラムは実行中です。


- 実行時のみ名前がわかるオブジェクトを検出するメソッド

Java リフレクション機構を使用すると、Java 仮想マシンにロードされたクラス情報を柔軟に検出できます機械。もちろん、この種の検出は操作のパフォーマンスを低下させるため、いつリフレクションを使用するかは、ニーズ、ビジネスの規模、経験の蓄積によって異なります。

では、リフレクション API を使用して実行時にクラスの情報を知るにはどうすればよいでしょうか?

コード例:

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();
    }
}
ログイン後にコピー

実行時に javax.swing.JFrame を入力すると、実行結果は次のようになります:

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

以上がJavaリフレクションの役割の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

See all articles