0x01の基本概念
Javaリフレクションメカニズムは実行状態にあり、どのクラスでも、このクラスのすべてのプロパティとメソッドを取得でき、どのオブジェクトでも、そのメソッドとプロパティ(プライベートメソッドとプロパティを含む)を呼び出すことができます。動的に情報を取得し、オブジェクトのメソッドを動的に呼び出す機能は、Java言語のリフレクションメカニズムと呼ばれます。
Javaリフレクションメカニズムは、脆弱性を悪用するための多くの便利さを提供します。その影は、多くのJava脆弱性の経験に見ることができます。したがって、Javaセキュリティの学習はそれを回避できません。
0x02
以前、リフレクションメカニズムで何ができるかはわかっていましたが、Javaは具体的にどのようにしてこれを実現していますか?これらには、Javaのいくつかのクラスが含まれます:クラス、コンストラクター、メソッド、フィールドオブジェクト指向プログラミングの経験を持つ学生は、クラスが一般に、以下のPersonクラスなど、特定のクラスの特性を抽象化することを知っています人の特性を抽象化し、これらの特性を操作するいくつかのメソッドを実装しました。
class Person{
private String name;
private int age;
private double height;
private double weight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public void show(){
System.out.println("xxxxxx");
}
}
したがって、今述べたいくつかのリフレクション関連クラスは同じです。ClassクラスはJavaのクラスの特性を抽象化していくつかのメソッドを提供し、ConstructorはJavaのすべてのコンストラクター関数の特性を抽象化していくつかを提供しますメソッド...(私が最初にJavaのセキュリティに触れたとき、私はしばしばJavaのクラスタイプに混乱していました)
これらのクラスを理解したら、调用一个对象的任意方法
この問題の実装方法に戻りましょう。次の3つのステップに進みます。
- まず、このオブジェクトに対応するClassクラスのインスタンスを取得します
- Classクラスには、クラスのすべての情報(属性、メソッド、コンストラクターなど)が格納されているため、Classクラスのインスタンスを通じて呼び出すメソッドを取得できます。
- 対応するメソッドを取得した後、対応するパラメーターをこのメソッドに渡して呼び出すことができます。
上記は一般的なプロセスです。次に、これらの3つのプロセスをコードで実装する方法を見ていきます。
後で詳しく説明するために、リフレクションを介してUserクラスのsetName()メソッドを呼び出す次の例を見てみましょう。
class User{
private String name;
private int age;
@Override
public String toString(){
return "User{" + "name=" +name + ", age="+age+"}";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
1. UserオブジェクトのClassインスタンスを取得します
Classインスタンスを取得するには3つの方法があります。
1.调用Class类的静态方法forName获取某个类的Class类实例:
Class clz = Class.forName("com.axin.User");
2.访问某个类的class属性,这个属性就存储着这个类对应的Class类的实例:
Class clz = com.axin.User.class;
3.调用某个对象的getClass()方法:
Class clz = (new User()).getClass();
2. setNameメソッドを取得する
メソッドクラスについてはすでに説明しましたが、Javaのすべてのメソッドはメソッドタイプであるため、リフレクションメカニズムを介してオブジェクトに到達するメソッドもメソッドタイプです。Classオブジェクトを通じてメソッドを取得します。
clz.getMethod(方法名,这个方法的参数类型)
例:
Method method = clz.getMethod("setName", String.class);
3. setNameメソッドを呼び出す
Methodクラスには、特定のメソッドを呼び出すためのinvokeメソッドがあります。使用方法は次のとおりです。
最初のパラメーターはメソッドを呼び出すオブジェクトで、2番目のパラメーターはこのメソッドに渡す必要のある可変長パラメーターです。説明は直感的ではありません。コードを見てください。
接着上文代码:
method.invoke((new User()), "axin");
或者
User user = new User();
method.invoke(user, "axin");
プロセスが終了しました。プログラム全体を見てみましょう。
setNameメソッドを正常に呼び出し、名前を "axin"に設定したことがわかります。
0x03
オブジェクトの任意のメソッドを呼び出すことに加えて、オブジェクトに対応するクラス名、すべての属性、およびすべてのメソッド名を取得することもできます。これらの内容はexpの記述にあまり使用されないため、ここでは記述しません。