0%

java反射1

前言:java反射1,本章总结了反射概念、反射的方法及实例等

反射概念

类加载器根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例

image-20200102231459147

image-20200102231514809

Java的反射利用加载到JVM中的.class文件来进行操作。.class文件中包含java类的所有信息,所以在运行状态中,使用Java反射对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。

image-20200102231529655

总结说:反射就是把java类中的各种成分映射成一个个的Java对象,并且可以进行操作,即方法(Method类)、属性(Filed类)、构造器(Constructor类)等等都是类

反射类

image-20200102231538619

image-20200102231709404

image-20200102231721315

image-20200102231740854

常用方法

获取类的 Class 对象实例
  • 使用 Class.forName(“classpath”)
1
Class clz = Class.forName("java.lang.String");
  • 使用 .class 方法
1
Class clz = String.class;
  • 使用类对象的 getClass() 方法
1
2
String str = new String("Hello");
Class clz = str.getClass();
获取类属性、方法、构造器
1
2
3
4
5
6
7
8
9
10
11
// 访问公有的成员变量
getFields()

// 所有已声明的成员变量,但不能得到其父类的成员变量
getDeclaredFields()

// 访问公有的成员方法
getMethods()

// 所有已声明的成员方法,但不能得到其父类的成员方法
getDeclaredMethods()
isInstance

关键字instanceof或者isInstance()方法用于判断是否为某个类的实例

通过反射创建类对象
1
2
1. 通过 Class 对象的 newInstance() 方法
1. getConstructor()获取构造器dui, Constructor 对象的 newInstance() 方法

实例

1
2
3
4
5
6
7
8
9
getName():获得类的完整名字
getFields():获得类的public类型的属性
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型
getConstructors():获得类的public类型的构造方法
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型
newInstance():通过类的不带参数的构造方法创建这个类的一个对象
Student.java
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
public class Student {
public String className;
private String id;
private String name;
private String college;
public Student() {};
public Student(String id, String name, String college) {
this.id = id;
this.name = name;
this.college = college;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCollege() {
return college;
}
public void setCollege(String college) {
this.college = college;
}

public static void function1(){
System.out.println("function1");
}
public void function2(Student student){
System.out.println("id: "+student.id+" name: "+student.name+" college: "+student.college);
}
private void function3(){
System.out.println("function3");
}
private Boolean function4(){
System.out.println("function4");
return true;
}
}
Test.java
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
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test {

public static void main(String[] args) {

try {
// className 应是类路径
String className = "test.Student";
// 获取Class 对象
Class<?> c = Class.forName(className);
// 同上
// Class<?> c = Student.class;

// 获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
System.out.println("\ngetDeclaredFields()\n");
for(int i=0;i<c.getDeclaredFields().length;i++)
{
System.out.println(c.getDeclaredFields()[i]);
}
// 获得某个类的所有的公共(public)的字段,包括父类中的字段。
System.out.println("\ngetFields()\n");
for(int i=0;i<c.getFields().length;i++)
{
System.out.println(c.getFields()[i]);
}

// 获得某个类的所有声明的方法,即包括public、private和proteced,但是不包括父类的申明方法。
System.out.println("\ngetDeclaredMethods()\n");
for(int i=0;i<c.getDeclaredMethods().length;i++)
{
System.out.println(c.getDeclaredMethods()[i]);
}
// 获得某个类的所有的公共(public)的方法,包括父类中的方法。
System.out.println("\ngetMethods()\n");
for(int i=0;i<c.getMethods().length;i++)
{
System.out.println(c.getMethods()[i]);
}
// 创建构造器
Constructor<?> constructor =c.getConstructor(String.class,String.class,String.class);
// 创建对象 等价于 Object obj = new Student();
Object obj1 = c.newInstance();
Object obj2 = constructor.newInstance("1","2","3");

Student student = (Student)obj1;
student.function2((Student)obj2);

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

}
}

私有属性

反射机制中可以获取private成员的值,但是要通过设置(setAccessible(true))进行暴力反射,解除权限。

1
2
3
4
5
Field[] f = obj.getDeclaredFields();
for(Field field : f){
field.setAccessible(true);
System.out.println(field.getName()+":"+field.get(obj.newInstance()));
}
-------------本文结束感谢您的阅读-------------