1つは、リフレクションを使用してメソッドを呼び出す
- 4つのキー
オブジェクト
メソッド名
実際のパラメータリスト
戻り値
public class User {
public int id;
private String name;
String address;
protected int sno;
public User() {
}
public User(int id, String name, String address, int sno) {
super();
this.id = id;
this.name = name;
this.address = address;
this.sno = sno;
}
public void study() {
System.out.println("study...");
}
public void eat(int a,String b) {
System.out.println("eat...");
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", address=" + address + ", sno=" + sno + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sno;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sno != other.sno)
return false;
return true;
}
}
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
Class usrClass = Class.forName("com.lzj.reflect.pojo.User");
Object obj = usrClass.newInstance();
Method eatMethod = usrClass.getDeclaredMethod("eat", int.class, String.class);
Object retValue = eatMethod.invoke(obj, 3,"lzj");
System.out.println(retValue);
}
}
2、invoke()
@CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor;
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
- 最初のパラメーターは、メソッドが属するオブジェクトです(静的メソッドの場合は、nullを直接渡すことができます)
- 2番目の変数パラメーターはメソッドのパラメーターです
- Method.invoke()自体は配列を使用してパラメーターをラップします。各呼び出しは、メソッドの可視性をチェックし(Method.invoke()で)、各実パラメーターと仮パラメーターの型の一致をチェックする必要があります(NativeMethodAccessorImplで)。 .invoke0()または生成されたJavaバージョンMethodAccessor.invoke())
1.実装の原則
- Invoke()は、実際にはそれ自体で実装されるリフレクション呼び出しロジックではありませんが、処理のためにsun.reflect.MethodAccessorに委任されます。実際の各Javaメソッドには、ルートとして対応するMethodオブジェクトが1つだけあり、このルートはユーザーに公開されません。 、ただし、リフレクションによってメソッドオブジェクトが取得されるたびに、ルートをラップする新しいメソッドオブジェクトが作成され、ユーザーに渡されます。実際のJavaメソッドに対応するメソッドオブジェクトのinvoke()メソッドが最初に呼び出される前に、オブジェクトはまだ作成されていません。最初の呼び出しで新しいMethodAccessorが作成され、rootに更新されるのを待ってから、MethodAccessor.invoke()を呼び出して実際にリフレクション呼び出しを完了します。