回転:反射でオブジェクトのプライベート属性とメソッドを呼び出す(クラシック)

1522 ワード

通常の呼び出しはオブジェクトのprivate修飾の属性と方法にアクセスできないことはよく知られていますが、これもjavaのカプセル化の原則です.
しかし、オブジェクトのprivate修飾の属性と方法に強制的にアクセスする方法はありますか?それは反射です!(これは面接問題で聞かれるかもしれませんよ)
次の例は簡単です.privateのプロパティdogNameとprivateのメソッドsayがあるdogクラスを定義します.
main関数で反射を使用してdogNameを変更し、sayメソッドを呼び出して印刷します.
ソース1:
package com.imooc.reflect;

public class Dog {
	//    
	private String dogName="  ";
	//     
	private void say(){
		System.out.println(dogName+":  ~~~");
	}
}

ソース2:
package com.imooc.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class DogTest {

	public static void main(String[] args) throws Exception{
		//  Dog  Class  
		Class class1 = Class.forName("com.imooc.reflect.Dog");
		//       
		Object object = class1.newInstance();
		
		//  dogName 
		Field dogName = class1.getDeclaredField("dogName");
		//  Field       
		dogName.setAccessible(true);
		// Field    "  ";
		dogName.set(object, "  ");
		
		//  say()  
		Method say = class1.getDeclaredMethod("say", new Class[]{});
		//  say       
		say.setAccessible(true);
		//  say  
		say.invoke(object, new Object[]{});
	}
}

ここでは特に注意しなければならない点があります.
反射でアクセス制御チェックを変更したい場合は、MethodとFieldオブジェクトを取得するときは必ずgetDeclaredFieldとgetDeclaredMethodを使用します.getFieldとgetMethodは使用しないでください.
両方のメソッドのパラメータは同じですが、getMethodとgetFieldではpublic修飾の属性とメソッドしか得られない点が異なります.getDeclaredは、この例ではプライベート属性とメソッドを呼び出すため、getDeclaredXXを使用する任意のタイプの属性とメソッドを取得できます.