【无标题】

动态代理

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 reflectClass对象的创建;
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 reflectClass对象的创建;
public class Student {
    public void sleep(){
        System.out.println("sleep......");
    }
}

反射测试类

package reflectClass对象的创建;
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反射机制的起源和人口

  1. 用于获取与类相关的各种信息
  2. 提供了获取类信息的相关方法
  3. Class类继承自Object类

Class是所以类的共同的图纸
1.每个类有自己的对象,好比图纸和实物的关系
2.每个类也可以看做是一个对象,有共同的图纸Class,存放类的结构信息,比如类的名字、属性、方法、构造方法、父类和接口,能够通过相应方法取出相应信息
Class类的对象称为类对象

6.Class对象功能
目录结构:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值