検索
ホームページJava&#&チュートリアルJava の原則 - 反映メカニズム

Java の原則 - 反映メカニズム

Dec 13, 2016 pm 02:06 PM
Javaのリフレクションメカニズム

学習: Java 原理 – リフレクション メカニズム

1. リフレクションとは:
リフレクションの概念は、1982 年に Smith によって最初に提案されました。これは主に、プログラムが自身の状態や動作にアクセス、検出、変更する能力を指します。この概念の導入により、コンピューター サイエンスの分野で応用反射率に関する研究が急速に始まりました。プログラミング言語設計の分野で初めて採用され、Lisp やオブジェクト指向でも成果を上げています。このうち、LEAD/LEAD++、OpenC++、MetaXa、OpenJavaはリフレクション機構をベースにした言語です。最近では、リフレクション メカニズムがウィンドウ システム、オペレーティング システム、ファイル システムにも適用されています。

コンピューターサイエンスはリフレクションの概念に新しい意味を与えましたが、リフレクション自体は新しい概念ではありません。コンピューター サイエンスでは、リフレクションとは、自己記述および自己制御型のアプリケーションのクラスを指します。つまり、この種のアプリケーションは、ある仕組みを利用して自身の動作の記述(自己表現)と監視(検査)を実現し、アプリケーションが記述した動作の状態や結果を、その記述に基づいて調整・修正することができます。自身の動作のステータスと結果。

2. Java のクラス リフレクションとは:
リフレクションは、Java プログラム開発言語の機能の 1 つであり、実行中の Java プログラム自体をチェックし、プログラムの内部を直接操作することができます。プロパティとメソッド。 Java のこの機能は実際のアプリケーションではあまり使用されませんが、この機能は他のプログラミング言語にはまったく存在しません。たとえば、Pascal、C、または C++ では、プログラム内の関数定義に関する情報を取得する方法がありません。
リフレクションは、Java が動的 (または準動的) 言語とみなされるための鍵であり、これにより、プログラムは実行中に、パッケージ、型パラメーター、スーパークラスなど、既知の名前を持つクラスの内部情報を取得できます。 、実装されたインターフェイス、内部クラス、外部クラス、フィールド、コンストラクター、メソッド、修飾子があり、実行中にインスタンスの生成、フィールドの内容の変更、またはメソッドの呼び出しを行うことができます。

3. Java クラス リフレクションに必要なクラス:
Java クラス リフレクションに必要なクラスは多くありません: フィールド、コンストラクター、クラス、オブジェクト。以下にこれらのクラスを簡単に説明します。
フィールド クラス: クラスまたはインターフェイスのプロパティに関する情報と、それらへの動的アクセスを提供します。反映されたフィールドは、クラス (静的) 属性またはインスタンス属性の場合があります。簡単に理解すると、反映クラスの属性をカプセル化したクラスとみなすことができます。
コンストラクター クラス: クラスの単一のコンストラクター メソッドとそのメソッドへのアクセスに関する情報を提供します。このクラスは、Field クラスとは異なります。Field クラスはリフレクション クラスのプロパティをカプセル化し、Constructor クラスはリフレクション クラスの構築メソッドをカプセル化します。
メソッド クラス: クラスまたはインターフェイスの単一メソッドに関する情報を提供します。反映されるメソッドは、クラス メソッドまたはインスタンス メソッド (抽象メソッドを含む) です。 このクラスは理解するのが難しくありません。リフレクション クラスのメソッドをカプセル化するために使用されるクラスです。
クラス: クラスのインスタンスは、実行中の Java アプリケーション内のクラスとインターフェイスを表します。列挙はクラスであり、アノテーションはインターフェイスです。各配列は、Class オブジェクトにマップされるクラスに属し、同じ要素の型と次元を持つすべての配列で共有されます。
オブジェクト クラス: すべてのクラスは、スーパー クラスとして Object を使用します。すべてのオブジェクト (配列を含む) は、このクラスのメソッドを実装します。

4. Java のリフレクション クラスでできること:
ここまで読んで、あなたは私が時間を無駄にしていると思っていると思います。以下では、それを説明するためにいくつかの簡単な例を使用します。
まず、Java のリフレクション メカニズムを通じて何が得られるかを見てみましょう。
まず、クラスを作成しましょう:

java code

 java.awt.event.ActionListener;  
import java.awt.event.ActionEvent;  
class A extends Object implements ActionListener{  
private int a = 3;  
public Integer b = new Integer(4);  
public A(){}  
public A(int id,String name){}  
public int abc(int id,String name){return 0;}  
public void actionPerformed(ActionEvent e){}  
}

私のクラスを見て混乱するかもしれません。私が何をしたいのか分からない場合は、このクラスを見ないでください。 . は、Object クラスを継承し、インターフェイス ActionListener、2 つのプロパティ int と Integer、2 つのコンストラクターと 2 つのメソッドがあることがわかります。これで十分です。
次に、クラス A の情報を学習するために、クラス A をリフレクション クラスとして使用します。まず、リフレクション クラスの属性と属性値を見てみましょう。

Javaコード

import java.lang.reflect.*;  
class B{  
public static void main(String args[]){  
A r = new A();  
Class temp = r.getClass();  
try{  
System.out.println("反射类中所有公有的属性");  
Field[] fb =temp.getFields();  
for(int j=0;j<fb.length;j++){  
Class cl = fb[j].getType();  
System.out.println("fb:"+cl);  
}  
  
System.out.println("反射类中所有的属性");  
Field[] fa = temp.getDeclaredFields();  
for(int j=0;j<fa.length;j++){  
Class cl = fa[j].getType();  
System.out.println("fa:"+cl);  
}  
System.out.println("反射类中私有属性的值");  
Field f = temp.getDeclaredField("a");  
f.setAccessible(true);  
Integer i = (Integer)f.get(r);  
System.out.println(i);  
}catch(Exception e){  
e.printStackTrace();  
}  
}  
  
}

这里用到了两个方法,getFields()、getDeclaredFields(),它们分别是用来获取反射类中所有公有属性和反射类中所有的属性的方法。另外还有getField(String)和getDeclaredField(String)方法都是用来过去反射类中指定的属性的方法,要注意的是getField方法只能取到反射类中公有的属性,而getDeclaredField方法都能取到。
这里还用到了Field 类的setAccessible方法,它是用来设置是否有权限访问反射类中的私有属性的,只有设置为true时才可以访问,默认为false。另外 Field类还有set(Object AttributeName,Object value)方法,可以改变指定属性的值。

下面我们来看一下如何获取反射类中的构造方法

java 代码

import java.lang.reflect.*;  
public class SampleConstructor {  
public static void main(String[] args) {  
A r = new A();  
printConstructors(r);  
}  
  
public static void printConstructors(A r) {  
Class c = r.getClass();  
//获取指定类的类名  
String className = c.getName();  
try {  
//获取指定类的构造方法  
Constructor[] theConstructors = c.getConstructors();  
for(int i=0; i<theConstructors.length; i++) {  
//获取指定构造方法的参数的集合  
Class[] parameterTypes = theConstructors[i].getParameterTypes();  
  
System.out.print(className + "(");  
  
for(int j=0; j<parameterTypes.length; j++)  
System.out.print(parameterTypes[j].getName() + " ");  
  
System.out.println(")");  
  
}  
}catch(Exception e) {  
e.printStackTrace();  
}  
}  
}

这个例子很简单,只是用getConstructors()方法获取了反射类的构造方法的集合,并用Constructor类的getParameterTypes()获取该构造方法的参数。

下面我们再来获取一下反射类的父类(超类)和接口

java 代码

import java.io.*;  
import java.lang.reflect.*;  
  
public class SampleInterface {  
public static void main(String[] args) throws Exception {  
A raf = new A();  
printInterfaceNames(raf);  
}  
  
public static void printInterfaceNames(Object o) {  
Class c = o.getClass();  
//获取反射类的接口  
Class[] theInterfaces = c.getInterfaces();  
for(int i=0; i<theInterfaces.length; i++)  
System.out.println(theInterfaces[i].getName());  
//获取反射类的父类(超类)  
Class theSuperclass = c.getSuperclass();  
System.out.println(theSuperclass.getName());  
}  
}

这个例子也很简单,只是用Class类的getInterfaces()方法获取反射类的所有接口,由于接口可以有多个,所以它返回一个 Class数组。用getSuperclass()方法来获取反射类的父类(超类),由于一个类只能继承自一个类,所以它返回一个Class对象。

下面我们来获取一下反射类的方法

java 代码

import java.lang.reflect.*;  
public class SampleMethod {  
  
public static void main(String[] args) {  
A p = new A();  
printMethods(p);  
}  
  
public static void printMethods(Object o) {  
Class c = o.getClass();  
String className = c.getName();  
Method[] m = c.getMethods();  
for(int i=0; i<m.length; i++) {  
//输出方法的返回类型  
System.out.print(m[i].getReturnType().getName());  
//输出方法名  
System.out.print(" "+m[i].getName()+"(");  
//获取方法的参数  
Class[] parameterTypes = m[i].getParameterTypes();  
for(int j=0; j<parameterTypes.length; j++){  
System.out.print(parameterTypes[j].getName());  
if(parameterTypes.length>j+1){  
System.out.print(",");  
}  
}  
  
System.out.println(")");  
}  
  
}  
  
}

这个例子并不难,它只是获得了反射类的所有方法,包括继承自它父类的方法。然后获取方法的返回类型、方法名和方法参数。

接下来让我们回过头来想一想,我们获取了反射类的属性、构造方法、父类、接口和方法,可这些东西能帮我们做些什么呢!!
下面我写一个比较完整的小例子,来说明Java的反射类能做些什么吧!!

java 代码

import java.lang.reflect.Constructor;  
import java.lang.reflect.Method;  
  
public class LoadMethod {  
public Object Load(String cName,String MethodName,String[] type,String[] param){  
Object retobj = null;  
try {  
//加载指定的Java类  
Class cls = Class.forName(cName);  
  
//获取指定对象的实例  
Constructor ct = cls.getConstructor(null);  
Object obj = ct.newInstance(null);  
  
//构建方法参数的数据类型  
Class partypes[] = this.getMethodClass(type);  
  
//在指定类中获取指定的方法  
Method meth = cls.getMethod(MethodName, partypes);  
  
//构建方法的参数值  
Object arglist[] = this.getMethodObject(type,param);  
  
//调用指定的方法并获取返回值为Object类型  
retobj= meth.invoke(obj, arglist);  
  
}  
catch (Throwable e) {  
System.err.println(e);  
}  
return retobj;  
}  
  
//获取参数类型Class[]的方法  
public Class[] getMethodClass(String[] type){  
Class[] cs = new Class[type.length];  
for (int i = 0; i < cs.length; i++) {  
if(!type[i].trim().equals("")||type[i]!=null){  
if(type[i].equals("int")||type[i].equals("Integer")){  
cs[i]=Integer.TYPE;  
}else if(type[i].equals("float")||type[i].equals("Float")){  
cs[i]=Float.TYPE;  
}else if(type[i].equals("double")||type[i].equals("Double")){  
cs[i]=Double.TYPE;  
}else if(type[i].equals("boolean")||type[i].equals("Boolean")){  
cs[i]=Boolean.TYPE;  
}else{  
cs[i]=String.class;  
}  
}  
}  
return cs;  
}  
  
//获取参数Object[]的方法  
public Object[] getMethodObject(String[] type,String[] param){  
Object[] obj = new Object[param.length];  
for (int i = 0; i < obj.length; i++) {  
if(!param[i].trim().equals("")||param[i]!=null){  
if(type[i].equals("int")||type[i].equals("Integer")){  
obj[i]= new Integer(param[i]);  
}else if(type[i].equals("float")||type[i].equals("Float")){  
obj[i]= new Float(param[i]);  
}else if(type[i].equals("double")||type[i].equals("Double")){  
obj[i]= new Double(param[i]);  
}else if(type[i].equals("boolean")||type[i].equals("Boolean")){  
obj[i]=new Boolean(param[i]);  
}else{  
obj[i] = param[i];  
}  
}  
}  
return obj;  
}  
}

这是我在工作中写的一个实现Java在运行时加载指定的类,并调用指定方法的一个小例子。这里没有main方法,你可以自己写一个。
Load方法接收的五个参数分别是,Java的类名,方法名,参数的类型和参数的值。

结束语:
Java 语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。Java reflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。Java 的这一特性非常强大,并且是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的。

但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Java開発のどの側面がプラットフォームに依存していますか?Java開発のどの側面がプラットフォームに依存していますか?Apr 26, 2025 am 12:19 AM

javadevelopmentisnotentirelylylypratform-IndopentDuetoseveralfactors.1)jvmvariationsaffectperformanceandbehavioracrossdifferentos.2)nativeLibrariesviajniintroducePlatform-specificissues.3)giaiasystemsdifferbeTioneplateplatifflics.4)

さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?Apr 26, 2025 am 12:15 AM

Javaコードは、さまざまなプラットフォームで実行するときにパフォーマンスの違いがあります。 1)JVMの実装と最適化戦略は、OracleJDKやOpenJDKなどとは異なります。 2)メモリ管理やスレッドスケジューリングなどのオペレーティングシステムの特性もパフォーマンスに影響します。 3)適切なJVMを選択し、JVMパラメーターとコード最適化を調整することにより、パフォーマンスを改善できます。

Javaのプラットフォームの独立性の制限は何ですか?Javaのプラットフォームの独立性の制限は何ですか?Apr 26, 2025 am 12:10 AM

java'splatformindepentedencehaslimitationsincludingporformanceoverhead、versioncompatibulisisues、changleSwithnativeLibraryIntegration、プラットフォーム固有の機能、およびjvminStallation/maintenation。

プラットフォームの独立性とクロスプラットフォーム開発の違いを説明します。プラットフォームの独立性とクロスプラットフォーム開発の違いを説明します。Apr 26, 2025 am 12:08 AM

PlatformEndependEncealLowsProgramStorunonAnyPlatformWithOdification、whilecross-platformdevelopmentReadreessomeplatform-specificAdjustments.platformindependence、explifiedByjava、unableSiversAlexecutionButMayCompromperformance

ジャストインタイム(JIT)コンピレーションは、Javaのパフォーマンスとプラットフォームの独立性にどのような影響を与えますか?ジャストインタイム(JIT)コンピレーションは、Javaのパフォーマンスとプラットフォームの独立性にどのような影響を与えますか?Apr 26, 2025 am 12:02 AM

jitcompalilationinjavaenhancesperformance whelemaintaining formindepence.1)itdynamicallyTrantesiNTODENATIVEMACHINECODEATRUNTIME、最適化されたコードを最適化すること、

Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Apr 25, 2025 am 12:23 AM

javaispopularforsoss-platformdesktopapplicationsduetoits "writeonce、runaynay" philosophy.1)itusesbytecodatiTatrunnanyjvm-adipplatform.2)ライブラリリケンディンガンドジャヴァフククレアティック - ルルクリス

Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Apr 25, 2025 am 12:22 AM

Javaでプラットフォーム固有のコードを作成する理由には、特定のオペレーティングシステム機能へのアクセス、特定のハードウェアとの対話、パフォーマンスの最適化が含まれます。 1)JNAまたはJNIを使​​用して、Windowsレジストリにアクセスします。 2)JNIを介してLinux固有のハードウェアドライバーと対話します。 3)金属を使用して、JNIを介してMacOSのゲームパフォーマンスを最適化します。それにもかかわらず、プラットフォーム固有のコードを書くことは、コードの移植性に影響を与え、複雑さを高め、パフォーマンスのオーバーヘッドとセキュリティのリスクをもたらす可能性があります。

プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?Apr 25, 2025 am 12:12 AM

Javaは、クラウドネイティブアプリケーション、マルチプラットフォームの展開、および言語間の相互運用性を通じて、プラットフォームの独立性をさらに強化します。 1)クラウドネイティブアプリケーションは、GraalvmとQuarkusを使用してスタートアップ速度を向上させます。 2)Javaは、埋め込みデバイス、モバイルデバイス、量子コンピューターに拡張されます。 3)Graalvmを通じて、JavaはPythonやJavaScriptなどの言語とシームレスに統合して、言語間の相互運用性を高めます。

See all articles

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、