通过 JAVA 提供的 API 实现一些反射操作

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
java复制代码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的实例就是运行时的类

  1. 通过类字面常量Class.class获取
1
java复制代码		Class clazz = Person.class;
  1. 通过Object类中的getClass()方法返回一个Class类型的实例
1
2
java复制代码		Person person = new Person();
Class clazz = person.getClass();
  1. 通过静态方法Class.forName("全类名")获取类名对应的Class对象
1
java复制代码		Class clazz = Class.forName("reflecttest.Person");

通过反射创建对象

反射创建类对象主要有两种方式,通过Class对象的newInstance()方法、通过Constructor对象的 newInstance()方法。

  1. 第一种:通过Class对象的newInstance()方法。
1
2
3
4
5
java复制代码		// 获取类的 Class 对象实例
Class clazz = Person.class;

//创建Person对象
Person person = (Person)clazz.newInstance();
  1. 第二种:通过Constructor对象的newInstance()方法
1
2
3
4
5
6
java复制代码		// 获取类的 Class 对象实例
Class clazz = Person.class;

//创建Person对象
Constructor constructor = clazz.getConstructor();
Person person = (Person)constructor.newInstance();

通过Constructor对象创建类对象可以选择特定构造方法,而通过 Class对象则只能使用默认的无参数构造方法。

示例:(调用有参构造方法进行类对象的初始化)

1
2
3
4
5
6
Java复制代码		// 获取类的 Class 对象实例
Class clazz = Person.class;

//创建Person对象
Constructor constructor = clazz.getConstructor();
Person person = (Person) constructor.newInstance("迪迦",16);

通过反射调用对象属性

获取属性

获取所有属性的两种方式

  1. getFields()
1
2
java复制代码		// 通过getFields()获取Person.class及父类中所有 public 修饰的属性
Field[] fields = clazz.getFields();
  1. getDeclaredFields()
1
2
java复制代码		// 通过getDeclaredFields()获取Person.class中所有的属性
Field[] fields = clazz.getDeclaredFields();

注:

getFields() 可以获取本类及父类中所有 public 修饰的属性
getDeclaredFields() 可以获取本类所有的属性。包括 public、private、protected、default 修饰的属性,不包括父类中的属性

获取指定属性的两种方式

  1. getField(String name)
1
2
java复制代码		// 通过getField()获取Person.class中的age属性		
Field field = clazz.getField("age");
  1. getDeclaredField(String name)
1
2
java复制代码		// 通过getDeclaredField()获取Person.class中的name属性
Field field = clazz.getDeclaredField("name");

注:

getField(String name) 可以获取本类及父类中的 public 修饰的属性
getDeclaredField(String name) 可以获取本类的属性。包括 public、private、protected、default 修饰的属性,不包括父类中的属性

对属性的操作

设置属性值

1
2
3
4
5
6
7
8
java复制代码		// 通过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)才能赋值

获取属性值

1
2
java复制代码		//通过get(Object obj)获取person对象的field属性
String name = (String) field.get(person);

获取属性的类型

1
2
3
4
5
java复制代码		//通过getType()获取属性的类型
Class type = field.getType();

//获取属性的类型名
String typename = field.getType().getName();

获取属性名

1
2
java复制代码		//调用getName()获取属性名
String fieldname = field.getName();

获取修饰类型

1
2
3
4
5
java复制代码		//调用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

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
java复制代码		// 获取类的 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;

通过反射调用对象方法

获取方法

获取所有方法的两种方式

  1. getMethods()
1
2
java复制代码		//通过getMethods()获取Person类及父类中所有的public修饰的方法		
Method[] methods =clazz.getMethods();
  1. getDeclaredMethods()
1
2
java复制代码		//通过getDeclaredMethods()获取Person类中所有的方法
Method[] methods = clazz.getDeclaredMethods();

注:

getMethods()可以获取本类及父类中所有 public 修饰的方法
getDeclaredMethods()可以获取本类所有的方法。包括 public、private、protected、default 修饰的方法,不包括父类中的方法

取指定方法的两种方式

用方法名和形参列表来确定获取的方法

  1. getMethod(String name, class<?>... parameterTypes)
1
2
java复制代码		//获取Person类中的show方法,参数为方法名,show()的形参列表
Method method =clazz.getMethod("show",String.class,int.class);
  1. getDeclaredMethod(String name, 类<?>... parameterTypes)
1
2
java复制代码		//获取Person类中的fly方法,参数为方法名,fly()无形参列表
Method method = clazz.getDeclaredMethod("fly");

注:

getMethod() 可以获取本类及父类中的 public 修饰的属性
getDeclaredMethod() 可以获取本类的属性。包括 public、private、protected、default 修饰的属性,不包括父类中的属性

对方法的操作

调用方法

1
2
3
4
5
6
7
8
9
10
java复制代码		//获取Person类中的fly方法,参数为方法名,fly()无形参列表
Method method = clazz.getDeclaredMethod("fly");

//如果方法是private修饰的,则需要设置访问权限
method.setAccessible(true);

//调用person中的fly方法
method.invoke(person);
//如果方法是静态方法static时,除了上面的方式,也可用下面的方法,当前类调用方法
//method.invoke(Person.class);

注:invoke()方法的返回值和调用的方法的返回值一样

获取方法的参数列表

1
2
java复制代码		//获取形参列表
Class[] paramTypes =method.getParameterTypes();

获取方法名

1
2
java复制代码		//获取方法名
String methodname = method.getName();

获取方法的修饰类型

1
2
3
java复制代码		//获取方法修饰符
int modifier = method.getModifiers();
String modifiername = Modifier.toString(modifier);

获取方法的返回值类型

1
2
3
4
5
java复制代码		//获取返回值类型
Class<?> returntype =method.getReturnType();

//获取返回值类型名
String returntypename = returntype.getName();

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
java复制代码	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);


通过反射调用对象构造方法

获取构造方法

获取所有构造方法的两种方式

  1. getConstructors()
1
2
java复制代码		//获取所有public修饰的构造方法,不包括父类
Constructor[] constructors = clazz.getConstructors();
  1. getDeclaredConstructors()
1
2
java复制代码		//获取所有构造方法,包括public、private、protected、default 修饰,不包括父类
Constructor[] constructors = getDeclaredConstructors();

注:

getConstructors()可以获取本类中所有 public 修饰的构造方法,不包括父类
getgetDeclaredConstructors()可以获取本类所有的构造方法。包括 public、private、protected、default 修饰的方法,不包括父类

获取指定构造方法的两种方式

对构造器的选择是依赖于形参列表的类型

  1. clazz.getConstructor()
1
2
java复制代码		//获取无参数的构造方法
Constructor constructor = clazz.getConstructor();
  1. getDeclaredConstructor()
1
2
java复制代码		//获取形参为(String,int)类型的构造方法
Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);

注:

getConstructor()只可以获取本类 public 修饰的构造方法,不包括父类
getDeclaredConstructor()可以获取本类所有的构造方法。包括 public、private、protected、default 修饰的方法,不包括父类

对构造方法的操作

创建对象

对构造器的选择是依赖于形参列表的类型

1
2
3
4
5
6
7
8
9
java复制代码		//获取空参的构造器
//Constructor constructor = clazz.getDeclaredConstructor();
Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);

//如果构造方法是private修饰的,设置权限
constructor.setAccessible(true);

//创建person对象
Person person = (Person)constructor.newInstance("迪迦",20);

获取构造方法的参数列表

1
2
java复制代码		//获取构造方法形参列表
Class[] paramTypes = constructor.getParameterTypes();

获取构造方法名

1
2
java复制代码		//获取构造方法名
String constructorname = constructor.getName();

获取构造方法的修饰类型

1
2
3
java复制代码		//获取构造方法的修饰符
int modifier = constructor.getModifiers();
String modifiername = Modifier.toString(modifier);

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
java复制代码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);

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%