动态代理
1.1什么是动态代理
动态代理利用Java的反射技术*(Java Reflection)*生成字节码
Java反射是Java被视为动态(或准动态)语言的一个关键性质。 这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、superclass(例如Object)、实现interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Reflection可以在运行时加载、探知、使用编译期间完全未知的classes。即Java程序可以加载一个运行时才得知名称的class,获取其完整构造,并生成器对象实体、或对其fields设置、或唤起其methods。
反射(reflection)允许静态语言在运行时(runtime)检查、修改程序的结构与行为。
在静态语言中,使用一个变量时,必须知道它的类型。在Java中,变量的类型信息在编译时都保存到了class文件中,这样在运行时才能保证准确无误;换句话说,程序在运行时的行为都是固定的。如果想在运行时改变,就需要反射这东西了。
反射的作用
(1)动态创建对象
(2)动态操作属性
(3)动态调用方法
(4)解耦合,提高程序的可扩展性。
反射的使用——通过反射获取类的五种方法
Class.forName(“全类名”);
将字节码文件加载进内存,返回Class对象,多用于配置文件,将类名定义在配置文件中,读取配置文件,加载类。
就是,通俗易懂的来说:通过类.Class获取
Class class1 = Class.forName("reflect中Class对象的创建.Person");
System.out.println("1:"+class1);
(2)第二种方式
类名.Class
通过类名的Class属性获取,多用于参数传递
Class class2=Person.class;
System.out.println("2:"+class2);
(3)第三种方式
对象.getClass()
getClass()方法在Object类中定义着。多用于对象获取字节码的方式
Person person=new Person();
Class class3 = person.getClass();
System.out.println("3:"+class3);
(第四种方法)
Class Clsaa=integer.TYPE对于内置类型的包装类,可以通过TYPE反射
Class class4= Integer.TYPE;
System.out.println("4:"+class4);
(5)第五种方式
Class class=class1.getSuperclass()
获取父类
Class class5 = class1.getSuperclass();
System.out.println("5:"+class5)
案例:
需求:声明一个Person类和Student用于完成基于五种方式来获取Class对象
资源:全类名:包名+类名,即全类名为reflect中Class对象的创建Person类的名字
对象的名字
目录结构如下:
Person类
package reflect中Class对象的创建;
public class Person {
private String name;
private int age;
public String a;
public String b;
public String c;
public String d;
public Person() {
}
//public reflect中Class对象的创建.Person(java.lang.String,int)
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
public String getD() {
return d;
}
private void setD(String d) {
this.d = d;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
", d='" + d + '\'' +
'}';
}
//重载方法的名称和参数
public void eat(){
System.out.println("eat......");
}
public void eat(String food){
System.out.println("eat....."+food);
}
}
学生类
package reflect中Class对象的创建;
public class Student {
public void sleep(){
System.out.println("sleep......");
}
}
反射测试类
package reflect中Class对象的创建;
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
Class class1 = Class.forName("reflect中Class对象的创建.Person");
System.out.println("1:"+class1);
//2.类名.class:通过类名的属性class获取
Class class2=Person.class;
System.out.println("2:"+class2);
//3.对象.getClass(),getClass()方法在Object类中定义着。
Person person=new Person();
Class class3 = person.getClass();
System.out.println("3:"+class3);
//4.Class class= Integer.TYPE
Class class4= Integer.TYPE;
System.out.println("4:"+class4);
//获取父类
Class class5 = class1.getSuperclass();
System.out.println("5:"+class5);
/**
* 同一个字节码文件(*.class)在一次程序运行过程中,
* 只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
*
* 地址判断的方式验证一下 ==
*/
System.out.println(class1==class2);
System.out.println(class1==class3);
//获取Student类的Class对象
Class class6 = Student.class;
System.out.println(class1==class6);
}
}
结论:她同一个字节码文件(*.Class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
4.反射机制常用的类文件
Java.lang.Class;
Java.lang.reflect.Constructor;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Modifier;
在JDK中,主要有以下类类实现Java反射机制,这些类都位于Java.lang.reflect包下
Class类:代表一个类
Constructor类:代表类的构造方法
Field类:代表类的成员变量(属性)
Method类:代表类的成员方法
5.反射的人口Class类
除了基本的数据类型外,其他类型都是Class类
Class类是Java反射机制的起源和人口
- 用于获取与类相关的各种信息
- 提供了获取类信息的相关方法
- Class类继承自Object类
Class是所以类的共同的图纸
1.每个类有自己的对象,好比图纸和实物的关系
2.每个类也可以看做是一个对象,有共同的图纸Class,存放类的结构信息,比如类的名字、属性、方法、构造方法、父类和接口,能够通过相应方法取出相应信息
Class类的对象称为类对象
6.Class对象功能
目录结构: