反射(一)

一、反射概述
反射要依赖于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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值