(CZ深入浅出Java基础)反射
一.类的加载
1.类初始化的时机
- 创建类的实例
- 访问类的静态变量,或者为静态变量赋值
- 调用类的静态方法
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
2.类加载器
2.1.作用
负责将.class文件加载到内在中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
2.2.分类
- Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
- Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
- Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
二.反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
class类包含:
成员变量 Field
构造方法 Consturctor
成员方法 Method
并且把这三个东西都看做对象
1.获取class文件对象的三种方式
1 public class Demo { 2 public static void main(String[] args) throws ClassNotFoundException { 3 //方式1 4 Person p=new Person(); 5 Class c=p.getClass(); 6 7 Person p2=new Person(); 8 Class c2=p.getClass(); 9 10 System.out.println(p==p2); 11 System.out.println(c==c2); 12 13 //方式2 14 Class c3=Person.class; 15 16 //方式3 17 Class c4=Class.forName("demo1.Person");//要全路径 18 } 19 }
2.通过反射获取无参构造方法并使用
1 package demo1; 2 3 import java.lang.reflect.Constructor; 4 5 public class Demo { 6 public static void main(String[] args) throws Exception { 7 Class c = Class.forName("demo1.Person");// 要全路径 8 9 // 获取构造方法 10 System.out.println("获取public构造方法"); 11 Constructor[] cons = c.getConstructors(); 12 for (Constructor constructor : cons) { 13 System.out.println(constructor); 14 } 15 16 System.out.println("获取所有构造方法"); 17 cons = c.getDeclaredConstructors(); 18 for (Constructor constructor : cons) { 19 System.out.println(constructor); 20 } 21 22 System.out.println("运用class字节码文件获取某个构造方法对象,并创建该类的实例"); 23 Constructor con = c.getConstructor(); 24 Object obj=con.newInstance(); 25 System.out.println(con); 26 } 27 } 28 29 class Person { 30 // 成员变量 31 private String name; 32 int age; 33 public String address; 34 35 // 构造方法 36 public Person() { 37 } 38 Person(String name, int age) { 39 this.name = name; 40 this.age = age; 41 } 42 public Person(String name, int age, String address) { 43 super(); 44 this.name = name; 45 this.age = age; 46 this.address = address; 47 } 48 49 // 成员方法 50 public void show() { 51 System.out.println("show"); 52 } 53 public void method(String s) { 54 System.out.println("method" + s); 55 } 56 public String getString(String s, int i) { 57 return s + "---" + i; 58 } 59 private void function() { 60 System.out.println("function"); 61 } 62 @Override 63 public String toString() { 64 return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; 65 } 66 }
3.通过反射去获得含参构造方法
1 package demo1; 2 3 import java.lang.reflect.Constructor; 4 5 public class Demo { 6 public static void main(String[] args) throws Exception { 7 Class c = Class.forName("demo1.Person");// 要全路径 8 9 System.out.println("运用class字节码文件获取某个构造方法对象,并创建该类的实例"); 10 Constructor con = c.getConstructor(String.class, int.class, String.class); 11 Object obj = con.newInstance("zxy",23,"Xi'an"); 12 System.out.println(obj); 13 } 14 } 15 16 class Person { 17 // 成员变量 18 private String name; 19 int age; 20 public String address; 21 22 // 构造方法 23 public Person() { 24 } 25 26 Person(String name, int age) { 27 this.name = name; 28 this.age = age; 29 } 30 31 public Person(String name, int age, String address) { 32 super(); 33 this.name = name; 34 this.age = age; 35 this.address = address; 36 } 37 38 // 成员方法 39 public void show() { 40 System.out.println("show"); 41 } 42 43 public void method(String s) { 44 System.out.println("method" + s); 45 } 46 47 public String getString(String s, int i) { 48 return s + "---" + i; 49 } 50 51 private void function() { 52 System.out.println("function"); 53 } 54 55 @Override 56 public String toString() { 57 return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; 58 } 59 }
4.获取私有构造方法
1 package demo1; 2 3 import java.lang.reflect.Constructor; 4 5 public class Demo { 6 public static void main(String[] args) throws Exception { 7 Class c = Class.forName("demo1.Person");// 要全路径 8 9 System.out.println("运用class字节码文件获取某个构造方法对象,并创建该类的实例"); 10 Constructor con = c.getDeclaredConstructor(String.class); 11 con.setAccessible(true);//取消Java语言的访问检查 12 Object obj = con.newInstance("zxy"); 13 System.out.println(obj); 14 } 15 } 16 17 class Person { 18 // 成员变量 19 private String name; 20 int age; 21 public String address; 22 23 // 构造方法 24 public Person() { 25 } 26 27 Person(String name, int age) { 28 this.name = name; 29 this.age = age; 30 } 31 32 private Person(String name) { 33 this.name = name; 34 } 35 36 public Person(String name, int age, String address) { 37 super(); 38 this.name = name; 39 this.age = age; 40 this.address = address; 41 } 42 43 // 成员方法 44 public void show() { 45 System.out.println("show"); 46 } 47 48 public void method(String s) { 49 System.out.println("method" + s); 50 } 51 52 public String getString(String s, int i) { 53 return s + "---" + i; 54 } 55 56 private void function() { 57 System.out.println("function"); 58 } 59 60 @Override 61 public String toString() { 62 return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; 63 } 64 }
5.通过反射调用方法
1 package demo1; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Method; 5 6 public class Demo { 7 public static void main(String[] args) throws Exception { 8 Class c = Class.forName("demo1.Person");// 要全路径 9 Constructor con = c.getConstructor(); 10 Object obj = con.newInstance(); 11 12 Method m1 = c.getMethod("show");//获取方法对象 13 m1.invoke(obj);//调用哪个对象的这个方法 14 15 Method m2 = c.getMethod("method", String.class); 16 m2.invoke(obj, "123"); 17 18 Method m3 = c.getDeclaredMethod("function"); 19 m3.setAccessible(true); 20 m3.invoke(obj); 21 } 22 } 23 24 class Person { 25 // 成员变量 26 private String name; 27 int age; 28 public String address; 29 30 // 构造方法 31 public Person() { 32 } 33 34 Person(String name, int age) { 35 this.name = name; 36 this.age = age; 37 } 38 39 private Person(String name) { 40 this.name = name; 41 } 42 43 public Person(String name, int age, String address) { 44 super(); 45 this.name = name; 46 this.age = age; 47 this.address = address; 48 } 49 50 // 成员方法 51 public void show() { 52 System.out.println("show"); 53 } 54 55 public void method(String s) { 56 System.out.println("method" + s); 57 } 58 59 public String getString(String s, int i) { 60 return s + "---" + i; 61 } 62 63 private void function() { 64 System.out.println("function"); 65 } 66 67 @Override 68 public String toString() { 69 return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; 70 } 71 }
6.通过反射调用成员变量
1 package demo1; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 6 public class Demo { 7 public static void main(String[] args) throws Exception { 8 Class c = Class.forName("demo1.Person");// 要全路径 9 Constructor con=c.getConstructor(); 10 Object obj=con.newInstance(); 11 Field addressField = c.getField("address"); 12 addressField.set(obj, "xian"); 13 System.out.println(obj); 14 } 15 } 16 17 class Person { 18 // 成员变量 19 private String name; 20 int age; 21 public String address; 22 23 // 构造方法 24 public Person() { 25 } 26 27 Person(String name, int age) { 28 this.name = name; 29 this.age = age; 30 } 31 32 private Person(String name) { 33 this.name = name; 34 } 35 36 public Person(String name, int age, String address) { 37 super(); 38 this.name = name; 39 this.age = age; 40 this.address = address; 41 } 42 43 // 成员方法 44 public void show() { 45 System.out.println("show"); 46 } 47 48 public void method(String s) { 49 System.out.println("method" + s); 50 } 51 52 public String getString(String s, int i) { 53 return s + "---" + i; 54 } 55 56 private void function() { 57 System.out.println("function"); 58 } 59 60 @Override 61 public String toString() { 62 return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; 63 } 64 }
7.通过用户的增删改查和学生登录注册引入中介
三.动态代理
代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
举例:春季回家买票让人代买
动态代理:在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理
(我也没太听懂)