java知识之反射

本文主要讲解反射的相关知识

一.获取类对象

  • getClass()class()forName()

1.获取类对象可以使用以下三种方法

  • 对象名调用getClass()方法
  • 类名调用class()方法
  • Class调用forName()方法,参数是类所在的文件相对路径

例子:Peo类

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class Peo {
private String name;
private int age;
public double heigth;
private double weight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeigth() {
return heigth;
}
public void setHeigth(double heigth) {
this.heigth = heigth;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public void run() {
System.out.println("peo is running");
}
private void run(String name) {
System.out.println(name + " is running");
}
void run(String name, String age) {
System.out.println(name + " is running , " + name + " is " + age);
}
protected void run(String name, String age, double heigth) {
System.out.println(name + " is running , " + name + " is " + age + " , " + name + " is " + heigth);
}
public void walk(String name) {
System.out.println("单参方法: " + name + " is walking");
}
public void jump() {
System.out.println("无参方法: " + "Peo is jumping");
}
// 无参构造方法
public Peo() {
}
// 单个参数构造方法,私有
private Peo(int age) {
this.age = age;
}
// 单个参数构造方法,受保护的
protected Peo(String name) {
this.name = name;
}
// 单个参数构造方法,默认不修饰
Peo(doubleweight) {
this.weight = weight;
}
// 多参构造方法
public Peo(String name, int age, double heigth, double weight) {
this.name = name;
this.age = age;
this.heigth = heigth;
this.weight = weight;
}
}

方法调用

1
2
3
4
5
6
7
Peo peo = new Peo();
// 对象名.getClass
Class c1 = peo.getClass();
// 类名.class
Class c2 = Peo.class;
// Class.forName("类所在的文件相对路径")
Class c3 = Class.forName("com.Case.Peo");

二.获取类的构造方法

  • getConstructors()getDeclaredConstructors()getConstructor()getDeclaredConstructor()

1.获取类的多个构造方法

  • 类对象调用getConstructors()方法 获取多个public修饰的构造方法
  • 类对象调用getDeclaredConstructors()方法 获取多个public、protected、private、和default修饰的构造方法
1
2
3
4
5
6
7
8
9
Class c2 = Peo.class;
Constructor[] constructors = c2.getConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println("constructors:" + constructors[i]);
}
Constructor[] declaredConstructors= c2.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) {
System.out.println("declaredConstructors:" + declaredConstructors[i]);
}

打印结果

1
2
3
4
5
6
7
8
constructors:public com.Case.Peo()
constructors:public com.Case.Peo(java.lang.String,int,int,int)
--------------------------------------------------------------
declaredConstructors:public com.Case.Peo()
declaredConstructors:private com.Case.Peo(int)
declaredConstructors:protected com.Case.Peo(java.lang.String)
declaredConstructors:com.Case.Peo(java.lang.double)
declaredConstructors:public com.Case.Peo(java.lang.String,int,double,double)

根据结果,getConstructors()方法,返回的是public修饰的构造方法,getDeclaredConstructors()返回的是public、protected、private、和default的构造方法

2.获取指定的无参构造方法

  • 类对象调用getConstructor()方法 获取无参构造方法
1
2
3
4
Peo peo = new Peo();
Class c1 = peo.getClass();
Constructor constructor = c1.getConstructor();
System.out.println("无参构造方法: " + constructor);

打印结果

1
无参构造方法: public com.Case.Peo()

3.获取指定的有参构造方法

  • 类对象调用getDeclaredConstructor(对应参数类型的类对象)方法 获取有参构造方法
1
2
3
4
Peo peo = new Peo();
Class c1 = peo.getClass();
Constructor constructorInt = c1.getDeclaredConstructor(int.class);
System.out.println("有参构造方法: " + constructorInt);

打印结果

1
有参构造方法: private com.Case.Peo(int)

注意:当构造方法是public修饰,使用getConstructor()或getDeclaredConstructor()都可以,其他修饰符,使用getDeclaredConstructor()获取构造方法,如果构造方法参数是int,方法中的参数为int.class,如果构造方法参数是String,方法中的参数为String.class,如果构造方法是public Peo(String name, int age, double heigth, double weight)
调用示例为:getDeclaredConstructor(“String.class, int.class, double.class, double.class“)

三.获取类的方法

  • getMethods()getDeclaredMethods()getMethod()getDeclaredMethod()

1.获取类的多个方法

  • 类对象调用getMethods()方法 获取多个public修饰的方法、继承类的public修饰的方法和该类所实现接口的方法
  • 类对象调用getDeclaredMethods()方法 获取多个public、protect、private、default修饰的方法和该类所实现接口的方法
1
2
3
4
5
6
7
8
9
Class c2 = Peo.class;
Method[] methods = c2.getMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println("methods:" + methods[i]);
}
Constructor[] declaredMethods= c2.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
System.out.println("declaredMethods:" + declaredMethods[i]);
}

打印结果

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
methods:public void com.Case.Peo.run()
methods:public java.lang.String com.Case.Peo.getName()
methods:public void com.Case.Peo.setName(java.lang.String)
methods:public void com.Case.Peo.setAge(int)
methods:public double com.Case.Peo.getHeigth()
methods:public double com.Case.Peo.getWeight()
methods:public int com.Case.Peo.getAge()
methods:public void com.Case.Peo.setWeight(double)
methods:public void com.Case.Peo.setHeigth(double)
methods:public void com.Case.Peo.walk(java.lang.String)
methods:public final void java.lang.Object.wait() throws java.lang.InterruptedException
methods:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
methods:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
methods:public boolean java.lang.Object.equals(java.lang.Object)
methods:public java.lang.String java.lang.Object.toString()
methods:public native int java.lang.Object.hashCode()
methods:public final native java.lang.Class java.lang.Object.getClass()
methods:public final native void java.lang.Object.notify()
methods:public final native void java.lang.Object.notifyAll()
-------------------------------------------------------------------------------------
declaredMethods:private void com.Case.Peo.run(java.lang.String)
declaredMethods:public void com.Case.Peo.run()
declaredMethods:void com.Case.Peo.run(java.lang.String,java.lang.String)
declaredMethods:protected void com.Case.Peo.run(java.lang.String,java.lang.String,double)
declaredMethods:public java.lang.String com.Case.Peo.getName()
declaredMethods:public void com.Case.Peo.setName(java.lang.String)
declaredMethods:public void com.Case.Peo.setAge(int)
declaredMethods:public double com.Case.Peo.getHeigth()
declaredMethods:public double com.Case.Peo.getWeight()
declaredMethods:public int com.Case.Peo.getAge()
declaredMethods:public void com.Case.Peo.setWeight(double)
declaredMethods:public void com.Case.Peo.setHeigth(double)

根据结果,Peo类继承Object, 所以getMethods()方法,返回的是public修饰的方法以及Object类中的方法, declaredMethods()返回的是public、private、protected和default修饰的方法以及该类所实现接口的方法,不返回继承类的方法.

2.获取指定的无参方法

  • 类对象调用getMethod(“方法名”)方法 获取无参方法,双引号中为方法名
1
2
3
4
5
6
Peo peo = new Peo();
Class c1 = peo.getClass();
// 获取无参的jump方法
Method methodJ = c1.getMethod("jump");
// 调用jump方法
methodJ.invoke(peo);

打印结果

1
无参方法: Peo is jumping

3.获取指定的有参方法

  • 类对象调用getMethod(“方法名”,对应参数类型的类对象)方法 获取有参方法,双引号中为方法名
1
2
3
4
5
6
Peo peo = new Peo();
Class c1= peo.getClass();
// 获取有参的walk方法
Method methodW = c1.getMethod("walk", String.class);
// 调用walk方法
methodW.invoke(peo, "xile");

打印结果

1
有参方法: xile is walking

四.获取类的成员变量

  • getFields()getDeclaredFields()getField()getDeclaredField()

1.获取类的多个成员变量

  • 类对象调用getFields()方法 获取多个public修饰的成员变量
  • 类对象调用getDeclaredFields()方法 获取多个public、protect、private、default修饰的成员变量
1
2
3
4
5
6
7
8
9
Class c2 = Peo.class;
Field[] fields = c1.getFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("fields:" + fields[i]);
}
Field[] declaredFields = c1.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
System.out.println("declaredFields:" + declaredFields[i]);
}

打印结果

1
2
3
4
5
fields:public double com.Case.Peo.heigth
declaredFields:private java.lang.String com.Case.Peo.name
declaredFields:private int com.Case.Peo.age
declaredFields:public double com.Case.Peo.heigth
declaredFields:private double com.Case.Peo.weight

根据结果,getFields()方法,返回的是public修饰的成员变量, declaredFields()返回的是public、private、protected和default修饰的成员变量.

2.获取指定的成员变量

  • 类对象调用getField(“成员变量名”)方法 获取指定的public修饰的成员变量
1
2
3
4
5
6
7
8
9
10
11
Peo peo = new Peo();
Class c1 = peo.getClass();
// 获取成员变量heigth
Field heigth = c1.getField("heigth");
// 获取Peo对象
Peo heigthObj = (Peo) c1.newInstance();
// 暴力反射
heigth.setAccessible(true);
// 设置成员变量的值
heigth.set(heigthObj, 180);
System.out.println("成员变量heigth: " + heigthObj.getHeigth());

打印结果

1
成员变量heigth: 180.0

3.获取指定的成员变量

  • 类对象调用getDeclaredgetField(“成员变量名”)方法 获取指定的public、protect、private、default修饰的成员变量
1
2
3
4
5
6
7
Peo peo = new Peo();
Class c1 = peo.getClass();
Field weight = c1.getDeclaredField("weight");
Peo weightObj = (Peo) c1.newInstance();
weight.setAccessible(true);
weight.set(weightObj, 140);
System.out.println("成员变量weight: " + weightObj.getWeight());

打印结果

1
成员变量weight: 140.0

注意:当成员变量是public修饰,使用getgetField()或getDeclaredgetField()都可以,其他修饰符,使用getDeclaredgetField()获成员变量