1、反射机制
1.1、反射机制有什么用?
通过java语言中的反射机制可以操作字节码文件。
优点可以读和修改字节码文件。
通过反射机制可以操作代码片段。(class文件。)
1.2、反射机制的相关类在哪个包下?
java.lang.reflect.*;
1.3、反射机制相关的重要的类有哪些?
java.lang.Class:代表整个字节码,代表一个类型,代表整个类。
java.lang.reflect.Method:代表字节码中的方法字节码。代表类中的方法。
java.lang.reflect.Constructor:代表字节码中的构造方法字节码。代表类中的构造方法
java.lang.reflect.Field:代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)。
java.lang.Class:
public class User{
// Field
int no;
// Constructor
public User(){
}
public User(int no){
this.no = no;
}
// Method
public void setNo(int no){
this.no = no;
}
public int getNo(){
return no;
}
}
2、获取到Class,能干什么?
1 package com.bjpowernode.java.reflect;
2
3 import com.bjpowernode.java.bean.User;
4
5 /*
6 获取到Class,能干什么?
7 通过Class的newInstance()方法来实例化对象。
8 注意:newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以。
9 */
10 public class ReflectTest02 {
11 public static void main(String[] args) {
12
13 // 这是不使用反射机制,创建对象
14 User user = new User();
15 System.out.println(user);
16
17 // 下面这段代码是以反射机制的方式创建对象。
18 try {
19 // 通过反射机制,获取Class,通过Class来实例化对象
20 Class c = Class.forName("com.bjpowernode.java.bean.User"); // c代表User类型。
21
22 // newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。
23 // 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
24 Object obj = c.newInstance();
25
26 System.out.println(obj); // com.bjpowernode.java.bean.User@10f87f48
27 } catch (ClassNotFoundException e) {
28 e.printStackTrace();
29 } catch (IllegalAccessException e) {
30 e.printStackTrace();
31 } catch (InstantiationException e) {
32 e.printStackTrace();
33 }
34 }
35 }
3、验证反射机制的灵活性
1 package com.bjpowernode.java.reflect;
2
3 import com.bjpowernode.java.bean.User;
4
5 import java.io.FileReader;
6 import java.util.Properties;
7
8 /*
9 验证反射机制的灵活性。
10 java代码写一遍,再不改变java源代码的基础之上,可以做到不同对象的实例化。
11 非常之灵活。(符合OCP开闭原则:对扩展开放,对修改关闭。)
12
13 后期你们要学习的是高级框架,而工作过程中,也都是使用高级框架,
14 包括: ssh ssm
15 Spring SpringMVC MyBatis
16 Spring Struts Hibernate
17 ...
18 这些高级框架底层实现原理:都采用了反射机制。所以反射机制还是重要的。
19 学会了反射机制有利于你理解剖析框架底层的源代码。
20 */
21 public class ReflectTest03 {
22 public static void main(String[] args) throws Exception{
23
24 // 这种方式代码就写死了。只能创建一个User类型的对象
25 //User user = new User();
26
27 // 以下代码是灵活的,代码不需要改动,可以修改配置文件,配置文件修改之后,可以创建出不同的实例对象。
28 // 通过IO流读取classinfo.properties文件
29 FileReader reader = new FileReader("chapter25/classinfo2.properties");
30 // 创建属性类对象Map
31 Properties pro = new Properties(); // key value都是String
32 // 加载
33 pro.load(reader);
34 // 关闭流
35 reader.close();
36
37 // 通过key获取value
38 String className = pro.getProperty("className");
39 //System.out.println(className);
40
41 // 通过反射机制实例化对象
42 Class c = Class.forName(className);
43 Object obj = c.newInstance();
44 System.out.println(obj);
45 }
46 }
4.Class.forName()发生了什么?
1 package com.bjpowernode.java.reflect;
2 /*
3 研究一下:Class.forName()发生了什么?
4 记住,重点:
5 如果你只是希望一个类的静态代码块执行,其它代码一律不执行,
6 你可以使用:
7 Class.forName("完整类名");
8 这个方法的执行会导致类加载,类加载时,静态代码块执行。
9
10 提示:
11 后面JDBC技术的时候我们还需要。
12 */
13 public class ReflectTest04 {
14 public static void main(String[] args) {
15 try {
16 // Class.forName()这个方法的执行会导致:类加载。
17 Class.forName("com.bjpowernode.java.reflect.MyClass");
18 } catch (ClassNotFoundException e) {
19 e.printStackTrace();
20 }
21 }
22 }