初認識java反射
14600 ワード
タイプ情報
一.Classオブジェクト
Classオブジェクトは、すべてのクラスのすべての「一般」オブジェクトを作成するために使用されます.JAvaはクラスオブジェクトを使用してRTTI(実行時にクラスとオブジェクトを識別する情報)を実行します.このような操作を実行していても.
クラスはプログラムの一部で、各クラスにはClassオブジェクトがあります.言い換えれば、新しいクラスが作成されるたびにClassオブジェクトが生成されます.このクラスのオブジェクトを生成するために、このプログラムを実行するjava仮想マシン(JVM)は、「クラスローダ」のサブシステムを使用します.
クラスローダサブシステムは、実際にはクラスローダチェーンを含むことができるが、JVM実装の一部であるオリジナルクラスローダは1つしかない.オリジナルクラスローダは、java APIクラスを含むいわゆる信頼性クラスをロードし、通常はローカルエリアからロードされる.このチェーンでは、通常、追加のクラス・ローダを追加する必要はありませんが、Webサーバ・アプリケーションをサポートするためにクラスを特定の方法でロードしたり、ネットワークでクラスをダウンロードしたりするなど、特別なニーズがある場合は、追加のクラス・ローダを接続する方法があります.
すべてのクラスは、最初に使用したときにJVMに動的にロードされ、プログラムがクラスの静的メンバーへの参照を作成するとロードされます.この証明コンストラクタもクラスの静的メソッドであり、コンストラクタの前にstaticキーワードが使用されていない場合でも、newオペレータを使用してクラスを作成する新しいオブジェクトは、クラスの静的メンバーへの参照として扱われます.
したがってjavaプログラムは、実行を開始する前に完全にロードされるのではなく、必要に応じてロードされます.
クラスローダはまず、クラスのClassオブジェクトがロードされているかどうかを確認します.まだロードされていない場合、デフォルトのクラスローダはクラス名に基づいて検索されます.classファイル(たとえば、追加のクラス・ローダがデータベースでバイトコードを検索する場合があります).このクラスのバイトコードがロードされると、破壊されていないことを確認するために検証を受けます.javaコードが含まれていません.
クラスのクラスオブジェクトがメモリにロードされると、そのクラスのすべてのオブジェクトを作成するために使用されます.
Class.forName(「クラス名」)は、指定されたクラス名に基づいて、そのようなオブジェクトを操作するための参照を取得できます.このメソッドで書かれたクラス名が見つからない場合、彼は例外ClassNotFoundExceptionを投げ出します.いつでも、実行時にタイプ情報を使用するには、まず適切なClassオブジェクトへの参照を取得する必要があります.Class.forName(「クラス名」)は、Classリファレンスを取得するためにこのタイプのオブジェクトを持つ必要がないため、この機能を実現する便利な方法です.ただし、オブジェクトが既に存在する場合(たとえば、オブジェクトがnewされている場合)、このオブジェクトはgetClassメソッドを呼び出してClass参照を取得できます.このメソッドはルートクラスObjectの一部に属し、オブジェクトの実際のタイプを表すClass参照を返します.
Classオブジェクトを使用すると、実行時にオブジェクトの完全なクラス継承構造を見つけることができます.
Classオブジェクトを取得する3つの方法
JAvaはまた、クラスの字面が常に明るい、文法が次のクラス名のようになっているClassオブジェクトへの参照を生成する別の方法を提供する.class
クラスの字面定数は、通常のクラスだけでなく、インタフェース、配列、および基本データ型にも適用できます.
「.class」を使用してClassオブジェクトへの参照を作成する場合、そのClassオブジェクトは自動的に初期化されません.クラスを使用するための準備には、次の3つのステップがあります.
1.3汎化Class参照
Classリファレンスは常にクラスのインスタンスを作成することができるClassオブジェクトを指し、これらのインスタンスを機能するすべてのメソッドコードを含む.クラスの静的メンバーも含まれているため、Class参照は、クラスのオブジェクトの正確なタイプを表し、そのオブジェクトはClassクラスのオブジェクトです.
Java SE 5の設計者は、クラス参照が指すクラスオブジェクトのタイプを限定することを許可することによって、そのタイプをより具体的にする機会を見定め、ここでは、クラスのように汎用化して所望のクラス参照を限定することができる汎用構文を用いる.
注意:Classを使用する場合.新Instance()インスタンスオブジェクトを取得する場合は、デフォルトのコンストラクタが必要です.そうしないと、例外が報告されます.
汎用構文をClassオブジェクトに使用する場合:newInstance()はオブジェクトの正確な情報を返します.Objectだけではありませんが、このオブジェクトのスーパークラスClassオブジェクトが手元にある場合は、このスーパークラスClassのnewInstance()メソッドを呼び出すと、Objectオブジェクトのみで受信できます.
二.タイプ変換前にチェック
現在知られているランタイム識別クラスのタイプ情報は、次の3つです.
三.反射はんしゃ:実行時のクラス情報じっこうじのクラスじょうほう
3.1反射とは何か、RTTIとの違い
主にプログラムが自身の状態や行為にアクセス、検出、修正できる能力を指す.重要なのは、反射に不思議なところはないことを認識し、反射を通じて未知のタイプのオブジェクトと付き合うとき、JVMの知識はこのオブジェクトがどの特定のクラスに属しているか(RTTIのように)を簡単に検査することである.他のことをする前にどのクラスのClassオブジェクトをロードする必要がありますか?だから、どのクラスのですか.classファイルは、JVMにとって取得可能である必要がある:すなわち、ローカルマシン上であるか、ネットワークを介して取得可能であるため、RTTIと反射との間の真の違いは、RTTIにとってコンパイラがコンパイル時に開き、チェックする.classファイル(言い換えれば、オブジェクトを通常の方法で呼び出すことができるすべての方法).しかし反射にとっては.classファイルはコンパイル時に取得できません.したがって、実行時に開く、チェックする.classファイル
Classクラスとjava.lang.reflectクラスライブラリは、Field,MethodおよびConstructorクラス(クラスごとにMemberインタフェースを実現する)を含む反射の概念をサポートする.これらのタイプのオブジェクトは、未知クラスに対応するメンバー情報を表すJVMによって実行時に作成する.これにより、Constructorで新しいオブジェクトを作成し、どのget()とset()メソッドでFieldオブジェクトに関連付けられたフィールドを読み取り、修正し、invoke()メソッドでMethodオブジェクトに関連付けられたメソッドを呼び出し、また、getFields()、getMethods()とgetConstructors()などの便利なメソッドを呼び出して、フィールド、メソッド、コンストラクタを表すオブジェクトの配列を返すことができます.
getDeclaredFields()とgetFields()メソッドの違い
クラスに属性がある場合、両方のメソッドは1つのField配列を返す.ここでgetDeclaredFields()メソッドはpublic,protected,default,privateを含むすべてのパラメータを返す.getFields()はpublicのパラメータのみを返す.getMethods()もgetConstructors()も同じです
次のdomainクラスがあり、彼のすべての属性情報、メソッド情報、コンストラクタの情報を実行時に読み出すことができます.
/**
* @description TBapInterParadomain
* @author [email protected]
* @date 20180301 15:47:23
* @review [email protected]/2018-03-01
*/
public class TBapInterPara{
/**
* UUID
*/
private String uuid;
/**
*
*/
private String fieldNm;
/**
*
*/
private String fieldTyp;
/**
*
*/
private String required;
/**
*
*/
private String remarks;
/**
*
*/
private String levelPara;
/**
* UUID
*/
private String infoUuid;
private ParameVo parameVo;
private List parameVos;
public TBapInterPara() {
super();
}
/**
* get UUID
*/
public String getUuid() {
return uuid;
}
/**
* set UUID
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}
/**
* get
*/
public String getFieldNm() {
return fieldNm;
}
/**
* set
*/
public void setFieldNm(String fieldNm) {
this.fieldNm = fieldNm;
}
/**
* get
*/
public String getFieldTyp() {
return fieldTyp;
}
/**
* set
*/
public void setFieldTyp(String fieldTyp) {
this.fieldTyp = fieldTyp;
}
/**
* get
*/
public String getRequired() {
return required;
}
/**
* set
*/
public void setRequired(String required) {
this.required = required;
}
/**
* get
*/
public String getRemarks() {
return remarks;
}
/**
* set
*/
public void setRemarks(String remarks) {
this.remarks = remarks;
}
/**
* get
*/
public String getLevelPara() {
return levelPara;
}
/**
* set
*/
public void setLevelPara(String levelPara) {
this.levelPara = levelPara;
}
/**
* get UUID
*/
public String getInfoUuid() {
return infoUuid;
}
/**
* set UUID
*/
public void setInfoUuid(String infoUuid) {
this.infoUuid = infoUuid;
}
}
/**
* @program: demo
* @description:
* @author: [email protected]
* @create: 2018-03-29 16:02
**/
public class Demo11 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class tBapInterParaClass=TBapInterPara.class;
Field[] fields = tBapInterParaClass.getDeclaredFields();// , private
Method[] methods = tBapInterParaClass.getMethods();
tBapInterParaClass.getDeclaredMethods();
Constructor>[] constructors = tBapInterParaClass.getConstructors();
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i].getType());
System.out.println(fields[i].getName());
System.out.println("-----------------");
}
System.out.println("methods:");
for (int k = 0; k < methods.length; k++) {
System.out.println(methods[k].getName());
System.out.println("-----------------");
}
System.out.println("constructors:");
for (int j = 0; j < constructors.length; j++) {
System.out.println(constructors[j]);
}
}
}
実行結果
class java.lang.String
uuid
-----------------
class java.lang.String
fieldNm
-----------------
class java.lang.String
fieldTyp
-----------------
class java.lang.String
required
-----------------
class java.lang.String
remarks
-----------------
class java.lang.String
levelPara
-----------------
class java.lang.String
infoUuid
-----------------
class tese2.ParameVo
parameVo
-----------------
interface java.util.List
parameVos
-----------------
methods:
getUuid
-----------------
setUuid
-----------------
getFieldNm
-----------------
setFieldNm
-----------------
getFieldTyp
-----------------
setFieldTyp
-----------------
getRequired
-----------------
setRequired
-----------------
getRemarks
-----------------
setRemarks
-----------------
getLevelPara
-----------------
setLevelPara
-----------------
getInfoUuid
-----------------
setInfoUuid
-----------------
wait
-----------------
wait
-----------------
wait
-----------------
equals
-----------------
toString
-----------------
hashCode
-----------------
getClass
-----------------
notify
-----------------
notifyAll
-----------------
constructors:
public tese2.TBapInterPara()