初识Java反射概念和使用

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

前言

  大家好,瑞雪后的第一天,每个周一的大家都期待这周五的来临。相信很多小伙伴上周末就两件事,赏雪和看EDG。哈哈 开始正题吧,今天聊一聊反射吧,在java中经常使用。

反射

  相信刚接触Java的,第一句肯定会问什么是反射呢?反射有什么作用呢?为什么使用反射呢?首先反射是Java的特征之一,项目中Java程序在运行的过程中,自动去识别并创建对应的类,能够动态的调用类的属性、构造方法、类中的方法。一句话描述:在程序中能动态调用不同的类和属性,去执行特定的操作。

  正因为反射能够在运行时动态加载需要的对象,所以很多框架中都使用到了反射。本次为了大家很好的理解反射,将基于反射创建对象、获取反射中的对象、获取类中属性、获取类中的构造方法、获取类中方法几个方面进行介绍,下面开始进入正题。

基础数据准备

  为了方便演示,创建了一个基础的对象类。并基于他进行本次的介绍。创建的演示类JueJinUser如下,包含四个属性,分别有get和set方法,还有toString方法,没有创建构造方法,下面会介绍通过反射自动创建的相关反射的方法。

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
js复制代码public class JueJinUser {
private Integer id;

private String name;

private String title;

private Integer age;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

@Override
public String toString() {
return "JueJinUser{" +
"id=" + id +
", name='" + name + '\'' +
", title='" + title + '\'' +
", age=" + age +
'}';
}
}

基于反射创建对象

  基于反射创建类对象主要有两种方式:第一种是通过类对象的newInstance()方法创建对象,第二种是通过构造器中的 newInstance()方法创建对象。

类对象的newInstance()方法

  类对象的newInstance()方法创建方法如下:

1
2
js复制代码       Class class = JueJinUser.class;
JueJinUser jueJinUseByClass = (JueJinUser) class.newInstance();
构造器的newInstance()方法
1
2
3
js复制代码        Class jueJinUserClass = JueJinUser.class;
Constructor constructor = jueJinUserClass.getConstructor();
JueJinUser jueJinUserByConstructor = (JueJinUser) constructor.newInstance();

  需要注意的是,两种创建方式中第一种基于类对象的newInstance()的方法只能是无参构造方法,而第二种基于构造器的 newInstance()方法可以有有参构造方法和无参构造方法,比较灵活。

获取反射中的对象

  获取反射对象的方式有三种,分别是:Class.forName、.class 方法和getClass() 方法。获取反射中对象的方法大家在项目中使用的还是比较多的,相信大家都不陌生。

Class.forName
1
js复制代码    Class clzForName = Class.forName("com.example.demo.module.JueJinUser");
.class 方法
1
js复制代码    Class clzForClass =JueJinUserString.class;
getClass() 方法
1
2
js复制代码    JueJinUser JueJinUser = new JueJinUser();
Class clzNewObject = str.getClass();

获取类中属性

  通过getFields和getDeclaredFields的方法,可以获取类中的属性信息,其中getFields可以获取类中的公有属性值,而getDeclaredFields的方法,获取所有类中的属性信息,但是无法获取到父类的信息。格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
js复制代码        Class clz = JueJinUser.class;
Field[] fields = clz.getFields();
System.out.println("--- getFields start ---");
for (Field field : fields) {
System.out.println(field.getName());
}
System.out.println("--- getFields end ---");


System.out.println("--- getDeclaredFields start ---");
Field[] declaredFields = clz.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field.getName());
}
System.out.println("--- etDeclaredFields end ---");

获取类中的构造方法

  通过getConstructors和getDeclaredConstructors的方法,可以获取类中的构造方法信息,其中getConstructors可以获取类中构造方法,而getDeclaredConstructors的方法,获取所有类中的构造方法,但是无法获取到父类的构造方法信息。格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
js复制代码     System.out.println("--- getConstructors start ---");
Constructor[] constructors = clz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName());
}
System.out.println("--- getConstructors end ---");

System.out.println("---getDeclaredConstructors start---");
Constructor[] declaredConstructors = clz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println(constructor.getName());
}
System.out.println("---getDeclaredConstructors end---");

获取类中方法

  通过getMethods和getDeclaredMethods的方法,可以获取类中的构造方法信息,其中getMethods可以获取类中构造方法,而getDeclaredMethods的方法,获取所有类中的方法,但是无法获取到父类的方法信息。格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
js复制代码
System.out.println("--- getMethods start ---");
Method[] methods = clz.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
System.out.println("--- getMethods end ---");


System.out.println("--- getDeclaredMethods start---");
Method[] declaredMethods = clz.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method.getName());
}
System.out.println("--- getDeclaredMethods end ---");

结语

  好了,以上就是反射的简单介绍,感谢您的阅读,希望您喜欢,如对您有帮助,欢迎点赞收藏。如有不足之处,欢迎评论指正。下次见。

  作者介绍:【小阿杰】一个爱鼓捣的程序猿,JAVA开发者和爱好者。公众号【Java全栈架构师】维护者,欢迎关注阅读交流。

本文转载自: 掘金

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

0%