Java反射
反射的概述
简述:能够分析类的详细信息的程序称为反射(reflective)
引入:为什么要学习反射?
反射是框架设计的灵魂 在我们常用的Spring系列的框架 就采用了大量的反射技术。
一、反射机制
- 在类运行时,分析类的行为及属性
- 在类运行时检查对象
- 实现泛型数组操作代码
简单而言就是 一个类运行期间,对于任意一个类,都能够获取这个类当中的所有属性以及方法
其中的属性和方法也可以进行访问和调用。
二、Class类
程序运行期间,Java运行时系统始终认为所有对象维护一个运行时类型的标识。虚拟机通过这些运行时类型信息可以选择要执行正确的方法。
使用一个特殊的Java类访问这些信息。保存这些信息的类名为Class,可能这会让我们会有点难受 xxx.class(字节码文件) 和我们获取的Class类有什么样的联系,后续再加以说明,先来看一个实例:
获取Class类对象的方式:
- 通过对象获取Class类对象
- 通过静态方法forName()
- 通过类的字节码
一、通过对象获取Class类对象
package com.reflection;
public class Student {
private String name; //学生姓名
private int age; //学生年龄
private String address; //学生所在地
public Student() {
}
public Student(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.reflection;
public class ClassTest {
public static void main(String[] args) {
//1.创建对象
Student s = new Student();
s.setName("张三");
//2.通过对象.getClass 获取所对应的Class类
Class<?> c = s.getClass();
System.out.println(c); //class com.reflection.Student 类的全限定名
System.out.println(c.getName() + "-->" + s.getName()); //获取Class类对应的类的全限定名
System.out.println(s.getClass().getName()); //与上述输出语句效果一致
}
}
二、通过forName()获取Class类对象
package com.reflection;
public class ClassTest2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//1.通过静态方法forName() 来获取类名对应的Class对象
Class<?> c = Class.forName("com.reflection.Student");
System.out.println(c.getName()); //获取类的全限定名
System.out.println(c.getConstructor()); //获取类的无参构造器
}
}
三、通过类的字节码,也是最快截的方式
package com.reflection;
import java.util.Random;
public class ClassTest3 {
public static void main(String[] args) {
Class<?> c = Student.class;
Class<?> c2 = int.class;
Class<?> c3 = Random.class;
/*
在这里我们就可以感受到反射的强大之处了
*/
System.out.println(c.getName());
System.out.println(c2.getName());
System.out.println(c3.getName());
}
}
注意:一个Class对象实际上表示的是一个类型,可能是类,也可能不是一个类。例如:int不是类 但int.class是一个Class类型的对象
类是可以实例化的 int是一种基本数据类型 如果有学过scala语言的小伙伴就知道Java是一种不彻底的面向对象语言,其中很显示的条件就是Java当中的基本数据类型不是对象。包装类才是对象!!
三、小结
后续将会再更,这一小节我们简单介绍了反射的相关概念,以及获取Class类对象的三种方式(还有一种类加载器的方式)