一、反射概述
反射要依赖于Class类。由于Class表示类文件的字节码文件对象,类字节码文件就是在描述一个类,描述类的成员变量、成员函数和构造函数。
而反射就是从一个类的字节码文件中拿到成员变量、成员函数和构造函数。要想从一个类中拿东西必须拿到这个类的字节码文件对象,所以反射依赖于Class,因此我们在学习反射之前先了解下Class。
1、Class类介绍
在Java中使用类来描述所有的事物,而这些描述完的所有程序,在编译完之后统一都会生成各自class文件。
在Java中class文件是所有源代码(.java 文件)程序编译后统一的结果。class文件是一类可以被JVM直接执行的文件。class文件在Java世界中就是存在的一类事物。
Java使用Class类来描述和封装class文件这类事物。class文件也叫作字节码文件。
说明:
1)Java中使用Class类表示某个class文件;
2)任何一个class文件都是Class这个类的一个实例对象;
Class的API描述:
说明:
1)Class类它可以表示Java中的任何内容;
2)Java中使用Class类表示硬盘上的某个.class文件,启动JVM就会把文件加载到内存中,占用一片空间,称为一个字节码文件对象,这个对象就是Class类的一个实例。不同的类,有自己的字节码文件对象,这些对象都是Class类的实例;
3)说明:在Class类中专门提供了几个获取成员变量 、成员函数 、构造函数的函数。
Field getField(String name) 表示获取类中的成员变量的对象;
Method getMethod() 表示获取类中的成员函数的对象;
Constructor getConstructor() 表示获取类中的构造函数的对象;
2、获取Class的三种方式(掌握)
因为反射技术是通过Class对象来实现把一个类进行解剖的,所以需要先了解怎么样才可以获取到Class对象。
需求:演示获取Class的三种方式:
1)获取Class对象的第一种方式:使用类的class属性直接获取:类名.class。
说明:在任何的一个类中都有一个静态成员变量class,可以直接获取到class文件所属的Class对象。
2)获取Class对象的第二种方式:在Object类中,有个getClass方法,就可以获取到任何一个对象对应的Class对象。对象.getClass()。
3)获取Class对象的第三种方式:在Class类中有个静态的方法:static Class forName(String className),根据类的名称获取类的Class对象。
说明:这里的参数className必须是类的全名(就是带有包名的全名称)。如:Class.forName("java.lang.String");
补充:上述三种方式可以获得Class对象,获得完Class对象就可以获取类的基本信息:
获取类的基本信息:
String getName() 获取类的名称,就是获得包名.类名
String getSimpleName() 获取类的简称 类名
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class ClassDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
// 方式1:类名.class
Class clazz = String. class ;
// 输出clazz全名 就是包名.类名 java.lang.String
System.out.println(clazz.getName());
// 输出clazz精简名字 就是类名 String
System.out.println(clazz.getSimpleName());
// 方式2:对象.getClass()
Class clazz2 = "柳岩" .getClass();
// 输出clazz2全名 就是包名.类名 java.lang.String
System.out.println(clazz2.getName());
// 输出clazz2精简名字 就是类名 String
System.out.println(clazz2.getSimpleName());
// 方式3:static Class forName(String className)根据类的名称获取类的Class对象
// Class clazz3 = Class.forName("String");//这里必须是类的全名 包名.类名,否则报java.lang.ClassNotFoundException
Class clazz3 = Class.forName( "java.lang.String" );
// 输出clazz3全名 就是包名.类名 java.lang.String
System.out.println(clazz3.getName());
// 输出clazz3精简名字 就是类名 String
System.out.println(clazz3.getSimpleName());
//说明对于String类来说在内存中只有一个String.class文件
System.out.println(clazz==clazz2); //true
System.out.println(clazz==clazz3); //true
System.out.println(clazz2==clazz3); //true
}
}
|
3、总结:
上述三种方式都是用来获取Class对象的,那么在开发中一般使用哪种获取方式呢?
在开发中我们会使用第三种获取方式。
说明:第三种的好处就是加载一个类却不需要知道这个类是什么,通过第一种方式获取前提是必须得先知道类名,然后才能通过类名.class获取。
而第二种方式必须知道对象才能通过对象.getClass()来获取。
而第三种不需要知道类名或者对象就可以直接获取,或者可以这样理解,我们在真实开发中,类的名字是不知道的,都是通过IO流来读取配置文件读取回来的。
也就是说我们读取配置文件的时候根据key来获取String类型的value,这样就可以把String类型的value作为forName(String className)函数的参数,而不需要在程序代码中体现出类名字样就可以获得Class对象了。
更多Java学习资料可关注:gzitcast