这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战
package reflecttest;
public class Person {
public int age;
private String name;
public Person() {
// TODO 自动生成的构造函数存根
}
public Person(String name) {
super();
this.name = name;
}
private Person(String name,int age) {
super();
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(String name,int age) {
System.out.println("迪迦,变身");
}
private void fly() {
System.out.println("迪迦,飞行");
}
private String Work(String name,int age) {
return name;
}
}
获取Class的实例的三种方式
Class的实例就是运行时的类
-
通过类字面常量
Class.class获取Class clazz = Person.class; -
通过
Object类中的getClass()方法返回一个Class类型的实例Person person = new Person(); Class clazz = person.getClass(); -
通过静态方法
Class.forName("全类名")获取类名对应的Class对象Class clazz = Class.forName("reflecttest.Person");
通过反射创建对象
反射创建类对象主要有两种方式,通过Class对象的newInstance()方法、通过Constructor对象的 newInstance()方法。
-
第一种:通过
Class对象的newInstance()方法。// 获取类的 Class 对象实例 Class clazz = Person.class; //创建Person对象 Person person = (Person)clazz.newInstance(); -
第二种:通过
Constructor对象的newInstance()方法// 获取类的 Class 对象实例 Class clazz = Person.class; //创建Person对象 Constructor constructor = clazz.getConstructor(); Person person = (Person)constructor.newInstance();
通过Constructor对象创建类对象可以选择特定构造方法,而通过 Class对象则只能使用默认的无参数构造方法。
示例:(调用有参构造方法进行类对象的初始化)
// 获取类的 Class 对象实例
Class clazz = Person.class;
//创建Person对象
Constructor constructor = clazz.getConstructor();
Person person = (Person) constructor.newInstance("迪迦",16);
通过反射调用对象属性
获取属性
获取所有属性的两种方式
-
getFields()// 通过getFields()获取Person.class及父类中所有 public 修饰的属性 Field[] fields = clazz.getFields(); -
getDeclaredFields()// 通过getDeclaredFields()获取Person.class中所有的属性 Field[] fields = clazz.getDeclaredFields();
注:
getFields()可以获取本类及父类中所有 public 修饰的属性getDeclaredFields()可以获取本类所有的属性。包括 public、private、protected、default 修饰的属性,不包括父类中的属性
获取指定属性的两种方式
-
getField(String name)// 通过getField()获取Person.class中的age属性 Field field = clazz.getField("age"); -
getDeclaredField(String name)// 通过getDeclaredField()获取Person.class中的name属性 Field field = clazz.getDeclaredField("name");
注:
getField(String name)可以获取本类及父类中的 public 修饰的属性getDeclaredField(String name)可以获取本类的属性。包括 public、private、protected、default 修饰的属性,不包括父类中的属性
对属性的操作
设置属性值
// 通过getDeclaredField()获取Person.class中的name属性
Field field = clazz.getDeclaredField("name");
//如果属性是private修饰的,则需要设置访问权限才能赋值
field.setAccessible(true);
//通过set(Object obj, Object value)设置person对象的name属性为"迪迦"
field.set(person, "迪迦");
注:如果属性是private修饰的,则需要设置
setAccessible(true)才能赋值
获取属性值
//通过get(Object obj)获取person对象的field属性
String name = (String) field.get(person);
获取属性的类型
//通过getType()获取属性的类型
Class type = field.getType();
//获取属性的类型名
String typename = field.getType().getName();
获取属性名
//调用getName()获取属性名
String fieldname = field.getName();
获取修饰类型
//调用getModifiers()获取修饰类型,
int modifier = field.getModifiers();
//Modifier.toString(int mod)转成public、private、protected、default
String modifiername = Modifier.toString(modifier);
注:0-
default、1-public、2-private、4-protected
示例
// 获取类的 Class 对象实例
Class clazz = Person.class;
//创建Person对象
Person person = (Person) clazz.newInstance();
// 通过getDeclaredField()获取Person.class中的name属性
Field field = clazz.getDeclaredField("age");
field.setAccessible(true);
//通过set()设置person对象的age属性为"12"
field.set(person, 12);
//获取修饰符
int modifier = field.getModifiers();
String modifiername = Modifier.toString(modifier);
//获取属性类型名
String typename = field.getType().getName();
//获取属性名
String fieldname = field.getName();
//获取属性值
int fieldvalue = field.getInt(person);
System.out.println(modifiername+" "+typename+" "+fieldname+" = "+fieldvalue+";");
输出:public int age = 12;
通过反射调用对象方法
获取方法
获取所有方法的两种方式
-
getMethods()//通过getMethods()获取Person类及父类中所有的public修饰的方法 Method[] methods =clazz.getMethods(); -
getDeclaredMethods()//通过getDeclaredMethods()获取Person类中所有的方法 Method[] methods = clazz.getDeclaredMethods();
注:
getMethods()可以获取本类及父类中所有 public 修饰的方法getDeclaredMethods()可以获取本类所有的方法。包括 public、private、protected、default 修饰的方法,不包括父类中的方法
取指定方法的两种方式
用方法名和形参列表来确定获取的方法
-
getMethod(String name, class<?>... parameterTypes)//获取Person类中的show方法,参数为方法名,show()的形参列表 Method method =clazz.getMethod("show",String.class,int.class); -
getDeclaredMethod(String name, 类<?>... parameterTypes)//获取Person类中的fly方法,参数为方法名,fly()无形参列表 Method method = clazz.getDeclaredMethod("fly");
注:
getMethod()可以获取本类及父类中的 public 修饰的属性getDeclaredMethod()可以获取本类的属性。包括 public、private、protected、default 修饰的属性,不包括父类中的属性
对方法的操作
调用方法
//获取Person类中的fly方法,参数为方法名,fly()无形参列表
Method method = clazz.getDeclaredMethod("fly");
//如果方法是private修饰的,则需要设置访问权限
method.setAccessible(true);
//调用person中的fly方法
method.invoke(person);
//如果方法是静态方法static时,除了上面的方式,也可用下面的方法,当前类调用方法
//method.invoke(Person.class);
注:invoke()方法的返回值和调用的方法的返回值一样
获取方法的参数列表
//获取形参列表
Class[] paramTypes =method.getParameterTypes();
获取方法名
//获取方法名
String methodname = method.getName();
获取方法的修饰类型
//获取方法修饰符
int modifier = method.getModifiers();
String modifiername = Modifier.toString(modifier);
获取方法的返回值类型
//获取返回值类型
Class<?> returntype =method.getReturnType();
//获取返回值类型名
String returntypename = returntype.getName();
示例
public static void main(String[] args) throws Exception, IllegalAccessException {
// 获取类的 Class 对象实例
Class clazz = Person.class;
//创建Person对象
Person person = (Person) clazz.newInstance();
//获取Person类中的方法
Method method = clazz.getDeclaredMethod("Work",String.class,int.class);
//设置权限
method.setAccessible(true);
//获取方法名
String methodname = method.getName();
//获取方法修饰符
int modifier = method.getModifiers();
String modifiername = Modifier.toString(modifier);
//获取返回值类型
Class<?> returntype =method.getReturnType();
//获取返回值类型名
String returntypename = returntype.getName();
//获取形参列表
Class[] paramTypes =method.getParameterTypes();
System.out.print(modifiername+" "+returntypename+" "+methodname+"(");
//打印方法参数
printParamTypes(paramTypes);
}
/**
* 打印方法参数
* @param paramTypes
*/
private static void printParamTypes(Class[] paramTypes) {
for (int j = 0; j < paramTypes.length; ++j) {
if (j > 0) {
System.out.print(",");
}
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
输出:private java.lang.String Work(java.lang.String,int);
通过反射调用对象构造方法
获取构造方法
获取所有构造方法的两种方式
-
getConstructors()//获取所有public修饰的构造方法,不包括父类 Constructor[] constructors = clazz.getConstructors(); -
getDeclaredConstructors()//获取所有构造方法,包括public、private、protected、default 修饰,不包括父类 Constructor[] constructors = getDeclaredConstructors();
注:
getConstructors()可以获取本类中所有 public 修饰的构造方法,不包括父类getgetDeclaredConstructors()可以获取本类所有的构造方法。包括 public、private、protected、default 修饰的方法,不包括父类
获取指定构造方法的两种方式
对构造器的选择是依赖于形参列表的类型
-
clazz.getConstructor()//获取无参数的构造方法 Constructor constructor = clazz.getConstructor(); -
getDeclaredConstructor()//获取形参为(String,int)类型的构造方法 Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);
注:
getConstructor()只可以获取本类 public 修饰的构造方法,不包括父类
getDeclaredConstructor()可以获取本类所有的构造方法。包括 public、private、protected、default 修饰的方法,不包括父类
对构造方法的操作
创建对象
对构造器的选择是依赖于形参列表的类型
//获取空参的构造器
//Constructor constructor = clazz.getDeclaredConstructor();
Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);
//如果构造方法是private修饰的,设置权限
constructor.setAccessible(true);
//创建person对象
Person person = (Person)constructor.newInstance("迪迦",20);
获取构造方法的参数列表
//获取构造方法形参列表
Class[] paramTypes = constructor.getParameterTypes();
获取构造方法名
//获取构造方法名
String constructorname = constructor.getName();
获取构造方法的修饰类型
//获取构造方法的修饰符
int modifier = constructor.getModifiers();
String modifiername = Modifier.toString(modifier);
示例
public static void main(String[] args) throws Exception, IllegalAccessException {
// 获取类的 Class 对象实例
Class clazz = Person.class;
//获取带参的构造器
Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);
//如果构造方法是private修饰的,设置权限
constructor.setAccessible(true);
//创建person对象
Person person = (Person)constructor.newInstance("迪迦",20);
//获取构造方法名
String constructorname = constructor.getName();
//获取构造方法的修饰符
int modifier = constructor.getModifiers();
String modifiername = Modifier.toString(modifier);
//获取构造方法形参列表
Class[] paramTypes = constructor.getParameterTypes();
System.out.print(modifiername+" "+constructorname+"(");
//打印方法参数
printParamTypes(paramTypes);
}
/**
* 打印方法参数
* @param paramTypes
*/
private static void printParamTypes(Class[] paramTypes) {
for (int j = 0; j < paramTypes.length; ++j) {
if (j > 0) {
System.out.print(",");
}
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
输出:private test1.Person(java.lang.String,int);