这是我参与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);