1.了解反射机制(学会查API帮助文档很重要!!)
1)反射机制有什么用?
可以操作(读和修改)字节码文件;可以操作代码片段(class文件)。
2)反射机制的相关类在哪个包下?
java.lang.reflect.* ;
3)反射机制相关的重要的类有哪些?
java.lang.Class:代表整个字节码,即整个类;
java.lang.reflect.Method:代表字节码中的方法字节码,即类中的方法;
java.lang.reflect.Constructor:代表字节码中的构造方法字节码,即类中的构造方法;
java.lang.reflect.Field;代表字节码中的属性字节码,即类中的成员变量(静态变量+实例变量);
2.获取字节码
要操作一个类的字节码,首先需要获取到这个类的字节码,那么怎么获取到这个类的 java.lang.Class 呢?
首先,通过查询API帮助文档,可以发现在java.lang包下的Class类中有两个静态方法:static Class<?> forName(String className)
和static Class<?> forName(String name, boolean initialize, ClassLoader loader)
,如下图:
可以看到,Class这个类比较特殊,好像不用new,而是直接调用forName方法,就可以返回一个Class对象,同时要注意,这个方法的参数是一个字符串,这个字符串就是你要获取字节码的类的完整类名(完整类名必须带有包名),
例如:
public class ReflectTest01 {
public static void main(String[] args) {
try {
Class c1 = Class.forName("java.util.Scanner");
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
上面这个c1就代表Scanner的class文件,即Scanner.class文件,或者说c1代表Scanner类型
3.tips1:所有的类中都有一个getClass()方法,比如说查一下API帮助文档,可以看到在Object类里,就有这个方法,如图:
那这个getClass()和上面的forName()返回的class文件有什么不同吗?
我们通过下面一个例子来看一下:
public class ReflectTest01 {
public static void main(String[] args) {
Class c2 = null;
try {
c2 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String s = "abc";
Class x = s.getClass();
System.out.println(c2 == x);
// ==判断的是对象的内存地址
}
}
运行结果:true
由此可以发现,这两种方式得到的class文件是一样的
4.tips2:Java中任何一种类型,包括基本数据类型,都有.class属性
例如:
Class a=String.class; //a代表String类型
Class b=double.class; //b代表double类型
这种方法也可以获取到class文件,并且和上面两种得到的是一样的,由此可见,有三种方式获取java.lang.CLass实例:
第一种 : Class c = Class.forName("完整类名带包名”);
第二种:Class c = 对象.getClass();
第三种: Class c = 任何类型.class;