(3)反射调用普通方法
在Class类中有如 下两种取得类中普通方法的函数:
A. 取得所有的普通方法:
public Method[] getMethods():获得所有的public修饰的方法(包含父列的方法也包含Object类)
public Method[] getDeclaredMethods():获得所有成员方法,包括私有的但不包括继承的。
B. 取得指定参数的普通方法:
public Method getMethod(String name,Class<?>... parameterTypes):
获得指定参数的权限为public的普通方法,
public Method getDeclaredMethod(String name,Class<?>... parameterTypes):
获得指定参数的成员方法,权限任意,且只能是本类中的方法。
C. 调用方法:
Method->public Object invoke(Object obj,Object……args):
obj:要调用的方法对象;args:调用方法时所传递的实参。
//反射调用普通方法
class Person1{
public void demon1() {}
protected void demon2() {}
private void demon3(String str) {}
}
class Person extends Person1{
private String name;
int age;
//无参构造方法
public Person() {}
public void print1() {
System.out.println("我是公有的普通方法1");
}
public void print2(int age) {
System.out.println("我是带有参数的公有的普通方法2"+age);
}
protected void print3() {
System.out.println("我是受保护、无参的普通方法3");
}
private String print4(String name) {
System.out.println("我是带有参数的私有的普通方法4");
return name;
}
void print() {
System.out.println("我是默认的普通方法5");
}
}
public class Test1{
public static void main(String[] args) throws ClassNotFoundException {
Class<?> class1 = Class.forName("reflect.Person");
System.out.println("*************获得访问权限为public的所有普通方法(包括父类、Object类)*********");
//获取所有访问权限为public的普通方法(包括父列和Object类)
Method[] methods = class1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("***************获得任意访问权限的所有普通方法(仅本类)**************");
//获取本类中任意访问权限的所有普通方法
Method[] methods2 = class1.getDeclaredMethods();
for (Method method : methods2) {
System.out.println(method);
}
System.out.println("***************获得public访问权限的普通方法(包括父类、Object类)**************");
try {
//获取访问权限为public的指定方法(包含父类和Object类)
Method method = class1.getMethod("print2", int.class);
System.out.println(method);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
System.out.println("***************获得任意访问权限的普通方法(仅本类)**************");
try {
//获取本类中任意访问权限的指定方法
Method method1 = class1.getDeclaredMethod("print4", String.class);
System.out.println(method1);
//实例化对象
Object obj = class1.getConstructor().newInstance();
//解除私有限定
method1.setAccessible(true);
//调用方法,需要两个参数,一个是要调用的对象(获取有反射),一个是实参
System.out.println("******************方法的调用***********************");
Object result = method1.invoke(obj,"lemon");
System.out.println(result);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
e.printStackTrace();
} 
(4)反射调用类中属性
在之前已经成功的实现了类的构造调用、方法调用,除了这两种模式之外还有类中属性调用。
前提:类中的所有属性一定在类对象实例化之后才会进行空间分配,所以此时如果要想调用类的属性,必须保证有实例化对象。通过反射的newInstance()可以直接取得实例化对象(Object类型)。
在Class类中提供有两组取得属性的方法:
A. public Field[] getFields():获取类中访问权限为public的所有属性。
public Field[] getDeclaredFields():获取所有属性,包括:私有、受保护、默认、公有;
B. public Field getField(String fieldName):获取指定权限为public的共有指定 属性
public Field getDeclaredField(String fieldName):获取任意权限的指定属性
//反射调用类中属性
class Person{
public String name;
int age;
private String work;
}
class Student extends Person{
private String classes;
protected char gender;
public long ID;
}
public class Test1{
public static void main(String[] args) throws Exception {
Class<?> class1 = Class.forName("reflect.Student");
//获取访问权限为public的所有属性(包含父类)
Field[] fields = class1.getFields();
System.out.println("***************获得权限为public的所有属性(包含父类)************************");
for (Field field : fields) {
System.out.println(field);
}
//获取访问权限任意的所有属性
Field[] fields2 = class1.getDeclaredFields();
System.out.println("***************获得本类中权限任意的所有属性************************");
for (Field field : fields2) {
System.out.println(field);
}
//获取访问权限为public的指定属性
Field field = class1.getField("name");
System.out.println("***************获得权限位public的的指定属性(包含父类)************************");
System.out.println(field);
//获取访问权限任意的本类中的指定属性
Field field2 = class1.getDeclaredField("classes");
System.out.println("***************获得本类中权限任意的指定属性************************");
System.out.println(field2);
}
}
C. 通过反射操作属性
通过反射机制我们可以利用set、get来动态的操作属性的值,若需要对private私有属性进行操纵时,则要用到AccessibleObject类中提供有一个方法:
public void setAccessible(boolean flag):动态设置封装性只此一次(指的是在当前的JVM中)。
Field类中还有一个重要方法:
public Class<?> getType():可以取得属性类型
package reflect;
import java.io.ObjectInputStream.GetField;
import java.lang.reflect.Field;
class Person1{
private String name;
}
public class Test2 {
public static void main(String[] args) throws Exception {
Class<?> class1 = Class.forName("reflect.Person1");
//实例化本类对象
Object object = class1.newInstance();
System.out.println(object);
//操作name属性
Field field = class1.getDeclaredField("name");
//取消封装
field.setAccessible(true);
//设置属性 相当于 对象.name = "lemon"
field.set(object, "lemon");
//取得属性
System.out.println(field.get(object));
//获取属性的类型(返回值:包名.类名)
System.out.println(field.getType());
//获取属性的类型(只返回类名)
System.out.println(field.getType().getSimpleName());
}
} 
本文深入探讨Java反射机制,包括如何通过反射调用类的方法及属性,解析不同访问权限的方法获取方式,并演示了如何实例化对象及操作私有属性。
——反射调用普通方法、类中属性&spm=1001.2101.3001.5002&articleId=80259092&d=1&t=3&u=5777259a4cd7486e813c0c80b044e60d)
825

被折叠的 条评论
为什么被折叠?



