1 Class

$\text {java.lang.Class}$

反射的基础,是类的类型标识。

  1. 构造器是私有的,Class 对象只能由 JVM 创建:
1
2
3
private Class(ClassLoader loader) {
classLoader = loader;
}
  1. 提供了获取类相关信息的核心方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获取类名
public String getName()
// 获取修饰符
public native int getModifiers()
// 获取父类
public native Class<? super T> getSuperclass()
// 获取接口
public Class<?>[] getInterfaces()
// 获取构造器
public Constructor<?>[] getDeclaredConstructors()
// 获取方法
public Method[] getDeclaredMethods()
// 获取字段
public Field[] getDeclaredFields()
  1. 反射的核心功能:
1
2
3
4
5
6
7
8
// 创建实例
public T newInstance()
// 获取方法
public Method getMethod(String name, Class<?>... parameterTypes)
// 获取字段
public Field getField(String name)
// 获取构造器
public Constructor<T> getConstructor(Class<?>... parameterTypes)

类加载时,JVM 创建对应的 Class 对象。

获取 Class 对象有以下三种主要方式:

  1. 通过类的 Class 属性:
1
Class<String> clazz1 = String.class;
  1. 通过对象的 getClass() 方法:
1
2
String str = "Hello World";
Class<? extends String> clazz2 = str.getClass();
  1. 通过 Class.forName() 静态方法:
1
2
3
4
5
try {
Class<?> clazz3 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

示例:比较 getSimpleNamegetNamegetCanonicalName

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
package com.solisamicus;

public class Test {
private class inner {
}

public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Test.class.getSimpleName()); // Test
System.out.println(Test.class.getName()); // com.solisamicus.Test
System.out.println(Test.class.getCanonicalName()); // com.solisamicus.Test

System.out.println(inner.class.getSimpleName()); // inner
System.out.println(inner.class.getName()); // com.solisamicus.Test$inner
System.out.println(inner.class.getCanonicalName()); // com.solisamicus.Test.inner

System.out.println(args.getClass().getSimpleName()); // String[]
System.out.println(args.getClass().getName()); // [Ljava.lang.String;
System.out.println(args.getClass().getCanonicalName()); // java.lang.String[]
}
}

Test
com.solisamicus.Test
com.solisamicus.Test
inner
com.solisamicus.Test$inner
com.solisamicus.Test.inner
String[]
[Ljava.lang.String;
java.lang.String[]

2 Constructor

$\text {java.lang.reflect.Constructor}$

1
2
3
4
Constructor<?>[] getConstructors()
Constructor<?>[] getDeclaredConstructors()
Constructor<T> getConstructor(Class<?>... params)
Constructor<T> getDeclaredConstructor(Class<?>... params)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.solisamicus;

public class User {
private String name;
private int age;

public User(String name) {
this.name = name;
}

private User(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "User{" + "age=" + age + ", name='" + name + '\'' + '}';
}
}
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
package com.solisamicus;

import java.lang.reflect.Constructor;

public class Main {
public static void main(String[] args) {
try {
Class<User> userClass = User.class;

System.out.println("=== constructors(public) ===");
Constructor<?>[] constructors = userClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}

System.out.println("\n=== constructors(public & private) ===");
Constructor<?>[] declaredConstructors = userClass.getDeclaredConstructors();
for (Constructor<?> constructor : declaredConstructors) {
System.out.println(constructor);
}

System.out.println("\n=== specific constructor(public) ===");
Constructor<User> constructor = userClass.getConstructor(String.class);
System.out.println(constructor);
User user1 = constructor.newInstance("jack");
System.out.println(user1);

System.out.println("\n=== specific constructor(public & private) ===");
Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class, int.class);
declaredConstructor.setAccessible(true);
User user2 = declaredConstructor.newInstance("Bob", 20);
System.out.println(user2);
} catch (Exception e) {
e.printStackTrace();
}
}
}

=== constructors(public) ===
public com.solisamicus.User(java.lang.String)

=== constructors(public & private) ===
public com.solisamicus.User(java.lang.String)
private com.solisamicus.User(java.lang.String,int)

=== specific constructor(public) ===
public com.solisamicus.User(java.lang.String)
User{age=0, name=‘jack’}

=== specific constructor(public & private) ===
User{age=20, name=‘Bob’}

3 Field

$\text {java.lang.reflect.Field}$

1
2
3
4
Field[] getFields()
Field[] getDeclaredFields()
Field getField(String name)
Field getDeclaredField(String name)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.solisamicus;

class Animal {
public String species;
protected int age;
private String name;

public Animal(String species, int age, String name) {
this.species = species;
this.age = age;
this.name = name;
}
}

class Dog extends Animal {
public String color;
private String breed;

public Dog(String species, int age, String name, String color, String breed) {
super(species, age, name);
this.color = color;
this.breed = breed;
}
}
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
91
92
93
94
95
96
97
98
99
100
package com.solisamicus;

import java.lang.reflect.Field;

public class Main {
public static void main(String[] args) {
try {
Class<Dog> dogClass = Dog.class;
Dog dog = new Dog("Canine", 3, "Max", "Brown", "Labrador");

System.out.println("=== fields(public), include inheritance fields ===");
Field[] fields = dogClass.getFields();
for (Field field : fields) {
System.out.println(field);
}

System.out.println("\n=== fields(public & private), not include inheritance fields ===");
Field[] declaredFields = dogClass.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}

System.out.println("\n=== specific field(public), include inheritance fields ===");
try {
Field speciesField = dogClass.getField("species");
System.out.println("Public field 'species': " + speciesField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'species'");
}

try {
Field ageField = dogClass.getField("age");
System.out.println("Protected field 'age': " + ageField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'age'");
}

try {
Field nameField = dogClass.getField("name");
System.out.println("Private field 'name': " + nameField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'name'");
}

try {
Field colorField = dogClass.getField("color");
System.out.println("Public field 'color': " + colorField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'color'");
}

try {
Field breedField = dogClass.getField("breed");
System.out.println("Private field 'breed': " + breedField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'breed'");
}

System.out.println("\n=== specific field(public & private), not include inheritance fields ===");
try {
Field speciesField = dogClass.getDeclaredField("species");
System.out.println("Public field 'species': " + speciesField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'species'");
}

try {
Field ageField = dogClass.getDeclaredField("age");
System.out.println("Protected field 'age': " + ageField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'age'");
}

try {
Field nameField = dogClass.getDeclaredField("name");
System.out.println("Private field 'name': " + nameField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'name'");
}

try {
Field colorField = dogClass.getDeclaredField("color");
System.out.println("Public field 'color': " + colorField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'color'");
}

try {
Field breedField = dogClass.getDeclaredField("breed");
breedField.setAccessible(true);
System.out.println("Private field 'breed': " + breedField.get(dog));
} catch (NoSuchFieldException e) {
System.out.println("Cannot access field 'breed'");
}

} catch (Exception e) {
e.printStackTrace();
}
}
}

=== fields(public), include inheritance fields ===
public java.lang.String com.solisamicus.Dog.color
public java.lang.String com.solisamicus.Animal.species

=== fields(public & private), not include inheritance fields ===
public java.lang.String com.solisamicus.Dog.color
private java.lang.String com.solisamicus.Dog.breed

=== specific field(public), include inheritance fields ===
Public field ‘species’: Canine
Cannot access field ‘age’
Cannot access field ‘name’
Public field ‘color’: Brown
Cannot access field ‘breed’

=== specific field(public & private), not include inheritance fields ===
Cannot access field ‘species’
Cannot access field ‘age’
Cannot access field ‘name’
Public field ‘color’: Brown
Private field ‘breed’: Labrador

总结:

修饰符 所属类 getFields() getDeclaredFields() getField() getDeclaredField()
public 父类
protected 父类
private 父类
public 子类
private 子类 ✓*
  • ✓ 表示可以访问
  • ✗ 表示不能访问
  • ✓* 表示需要设置 setAccessible(true) 才能访问

4 Method

$\text {java.lang.reflect.Method}$

1
2
3
4
Method[] getMethods()
Method[] getDeclaredMethods()
Method getMethod(String name, Class<?>... params)
Method getDeclaredMethod(String name, Class<?>... params)

示例:

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
package com.solisamicus;

class Animal {
public String species;
protected int age;
private String name;

public Animal(String species, int age, String name) {
this.species = species;
this.age = age;
this.name = name;
}

public void makeSound() {
System.out.println("Animal makes sound");
}

protected void eat() {
System.out.println("Animal eats");
}

private void sleep() {
System.out.println("Animal sleeps");
}
}

class Dog extends Animal {
public String color;
private String breed;

public Dog(String species, int age, String name, String color, String breed) {
super(species, age, name);
this.color = color;
this.breed = breed;
}

@Override
public void makeSound() {
System.out.println("Dog barks");
}

public void fetch() {
System.out.println("Dog fetches");
}

private void wagTail() {
System.out.println("Dog wags tail");
}
}
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.solisamicus;

import java.lang.reflect.Method;

public class Main {
public static void main(String[] args) {
try {
Class<Dog> dogClass = Dog.class;
Dog dog = new Dog("Canine", 3, "Max", "Brown", "Labrador");

System.out.println("=== methods(public), include inheritance methods ===");
Method[] methods = dogClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}

System.out.println("\n=== methods(public & private), not include inheritance methods ===");
Method[] declaredMethods = dogClass.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}

System.out.println("\n=== specific method(public), include inheritance methods ===");
try {
Method parentMakeSound = dogClass.getMethod("makeSound");
System.out.println("Parent's overridden public method 'makeSound': ");
parentMakeSound.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'makeSound' from parent");
}

try {
Method parentEat = dogClass.getMethod("eat");
System.out.println("Parent's protected method 'eat': ");
parentEat.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'eat' from parent");
}

try {
Method parentSleep = dogClass.getMethod("sleep");
System.out.println("Parent's private method 'sleep': ");
parentSleep.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'sleep' from parent");
}

try {
Method fetch = dogClass.getMethod("fetch");
System.out.println("Child's public method 'fetch': ");
fetch.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'fetch'");
}

try {
Method wagTail = dogClass.getMethod("wagTail");
System.out.println("Child's private method 'wagTail': ");
wagTail.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'wagTail'");
}

System.out.println("\n=== specific method(public & private), not include inheritance methods ===");
try {
Method parentMakeSound = dogClass.getDeclaredMethod("makeSound");
System.out.println("Parent's overridden public method 'makeSound': ");
parentMakeSound.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'makeSound' from parent");
}

try {
Method parentEat = dogClass.getDeclaredMethod("eat");
System.out.println("Parent's protected method 'eat': ");
parentEat.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'eat' from parent");
}

try {
Method parentSleep = dogClass.getDeclaredMethod("sleep");
System.out.println("Parent's private method 'sleep': ");
parentSleep.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'sleep' from parent");
}

try {
Method fetch = dogClass.getDeclaredMethod("fetch");
System.out.println("Child's public method 'fetch': ");
fetch.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'fetch'");
}

try {
Method wagTail = dogClass.getDeclaredMethod("wagTail");
wagTail.setAccessible(true);
System.out.println("Child's private method 'wagTail': ");
wagTail.invoke(dog);
} catch (NoSuchMethodException e) {
System.out.println("Cannot access method 'wagTail'");
}

} catch (Exception e) {
e.printStackTrace();
}
}
}

=== methods(public), include inheritance methods ===
public void com.solisamicus.Dog.makeSound()
public void com.solisamicus.Dog.fetch()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

=== methods(public & private), not include inheritance methods ===
public void com.solisamicus.Dog.makeSound()
private void com.solisamicus.Dog.wagTail()
public void com.solisamicus.Dog.fetch()

=== specific method(public), include inheritance methods ===
Parent’s overridden public method ‘makeSound’:
Dog barks
Cannot access method ‘eat’ from parent
Cannot access method ‘sleep’ from parent
Child’s public method ‘fetch’:
Dog fetches
Cannot access method ‘wagTail’

=== specific method(public & private), not include inheritance methods ===
Parent’s overridden public method ‘makeSound’:
Dog barks
Cannot access method ‘eat’ from parent
Cannot access method ‘sleep’ from parent
Child’s public method ‘fetch’:
Dog fetches
Child’s private method ‘wagTail’:
Dog wags tail

总结:

修饰符 所属类 getMethods() getDeclaredMethods() getMethod() getDeclaredMethod()
public 父类/子类
protected 父类
private 父类
public 子类
private 子类 ✓*
  • ✓ 表示可以访问
  • ✗ 表示不能访问
  • ✓* 表示需要设置 setAccessible(true) 才能访问