一、获取当前类的父类:直接调用Class对象的getSuperClass()方法
package test.com.atguigu.javase.lesson12;
import org.junit.Test;
/**
* 获取当前类的父类
* 直接调用Class对象的getSuperClass()方法
* @throws Exception
*/
public class GetSuperClassTestTest {
@Test
public void testGetSuperClass() throws Exception {
String className = "com.atguigu.javase.lesson12.Student";
Class clazz = Class.forName(className);
Class superClazz = clazz.getSuperclass();
System.out.println(superClazz);
}
}
二、若需要通过反射执行私有方法,需要method.setAccessible(true)这一步操作
Student类:
package com.atguigu.javase.lesson12;
public class Student extends Person {
private void method1(Integer age){
System.out.println("private void method1");
}
}
InvokePrivateMethodTest类
package test.com.atguigu.javase.lesson12;
import com.atguigu.javase.lesson12.Student;
import org.junit.Test;
import java.lang.reflect.Method;
public class InvokePrivateMethodTestTest {
/**
* 若通过Method的invoke()方法调用方法,而访问权限不足,则可以先使该方法变为可访问的:
* method.setAccessible(true)
*
* @throws Exception
*/
@Test
public void testInvokePrivateMethod() throws Exception {
Object obj = new Student();
Class clazz = obj.getClass();
Method method = clazz.getDeclaredMethod("method1",Integer.class);
System.out.println(method);
//若通过反射执行私有方法
method.setAccessible(true);
method.invoke(obj,10);
}
}
三、获取父类中私有方法,采用循环向上转型的方式获得
Person类:
package com.atguigu.javase.lesson12;
public class Person {
String name;
private int age;
private void test() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("name:" + name);
}
public void setName(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("name:" + name);
System.out.println("age:" + age);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("有参数的构造器");
}
public Person() {
System.out.println("无参数的构造器");
}
private String method2() {
return "private String method2";
}
}
UtilTest类:
package test.com.atguigu.javase.lesson12;
import com.atguigu.javase.lesson12.Student;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class UtilTestTest {
/**
* 既可以访问本类私有方法, 也可以访问父类的私有方法
*
* @param obj 放法执行的那个对象
* @param methodName 类的一个方法的方法名该方法也可能是私有方法
* @param args 调用该方法需要传入的参数
* @return 调用方法后的返回值
* @throws NoSuchMethodException
*/
public Object invoke(Object obj, String methodName, Object... args) throws NoSuchMethodException {
Class clazz = obj.getClass();
Class[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
Method method = getMethod(clazz, methodName, parameterTypes);
method.setAccessible(true);
try {
return method.invoke(obj, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取clazz的methodName方法,该方法可能是私有方法,还可能是父类中的私有方法
*
* @param clazz
* @param methodName
* @param parameterTypes
* @return
*/
public Method getMethod(Class clazz, String methodName, Class... parameterTypes) {
for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
try {
Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
return method;
} catch (Exception e) {
}
}
return null;
}
@Test
public void testInvoke() throws NoSuchMethodException {
Object obj = new Student();
invoke(obj, "method1", 10);
Object object = invoke(obj, "method2");
System.out.println(object);
}
@Test
public void testGetMethod() throws ClassNotFoundException {
Class clazz = Class.forName("com.atguigu.javase.lesson12.Student");
Method method = getMethod(clazz, "method1", Integer.class);
System.out.println(method);
method = getMethod(clazz, "method2");
System.out.println(method);
}
}
四、练习
package test.com.atguigu.javase.lesson12;
import com.atguigu.javase.lesson12.Student;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class UtilTestTest {
/**
* 既可以访问本类私有方法, 也可以访问父类的私有方法
*
* @param obj 放法执行的那个对象
* @param methodName 类的一个方法的方法名该方法也可能是私有方法
* @param args 调用该方法需要传入的参数
* @return 调用方法后的返回值
* @throws NoSuchMethodException
*/
public Object invoke(Object obj, String methodName, Object... args) throws NoSuchMethodException {
Class clazz = obj.getClass();
Class[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
Method method = getMethod(clazz, methodName, parameterTypes);
method.setAccessible(true);
try {
return method.invoke(obj, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取clazz的methodName方法,该方法可能是私有方法,还可能是父类中的私有方法
*
* @param clazz
* @param methodName
* @param parameterTypes
* @return
*/
public Method getMethod(Class clazz, String methodName, Class... parameterTypes) {
for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
try {
Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
return method;
} catch (Exception e) {
}
}
return null;
}
@Test
public void testInvoke() throws NoSuchMethodException {
Object obj = new Student();
invoke(obj, "method1", 10);
Object object = invoke(obj, "method2");
System.out.println(object);
}
@Test
public void testGetMethod() throws ClassNotFoundException {
Class clazz = Class.forName("com.atguigu.javase.lesson12.Student");
Method method = getMethod(clazz, "method1", Integer.class);
System.out.println(method);
method = getMethod(clazz, "method2");
System.out.println(method);
}
/**
*
*/
@Test
public void testClassMethod() throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
//全类名
String className = "com.atguigu.javase.lesson12.Student";
//方法名,可能在上一步给的类中,也可能在父类中,可能私有,可能共有
String methodName = "method3";
//执行上一步对应的方法时需要传入的参数列表
Object[] args = {"Jerry", 24};
//根据以上条件,执行methodName对应的方法,并打印返回值
//1.加载className对应的类,获取对应的Class对应clazz
Class clazz = Class.forName(className);
//2.调用clazz的getDeclaredMethod()方法获取对应的Method对象
//注意:
//2.1 因为该方法可能不在当前类中,所以有可能去父类中获取
//2.2 因为给定的条件中并没有给定参数类型的列表,需要从args来获取参数类型的列表
Class[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
Method method = null;
for (Class clazz2 = clazz; clazz2 != Object.class; clazz2 = clazz2.getSuperclass()) {
try {
method = clazz2.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
}
}
//3.因为Method可能是私有的,所以需要让其变为可被访问:setAccessible(true)
method.setAccessible(true);
//4. 调用Method
//4.1 利用1得到的clazz先创建className对应的类的一个对象
Object obj = clazz.newInstance();
//4.2 再调用Method的invoke()方法执行方法
Object result = method.invoke(obj, args);
System.out.println(result);
}
}