反射的学习

1.反射机制概述

运行时的特性。因为它的动态性。通常写一些通用的东西。

反射,比如在前端传过来一个对象,需要通过反射来操作。

反射为什么赤裸,因为类加载到内存里了,反射的操作是在内存中动手。

 

1.1 反射可以做的小例子。

  调用私有的时候,后面setAccessible为true。就可以用

 1.2如何看待反射机制和面向对象封装性?

不矛盾,封装性是建议怎么调用结构。

反射是研究想调用哪个。

1.3什么时候用反射?

可以直接new造对象,操作属性。也可以反射来操作。、

反射特征:动态性。

如果编译的时候确定不下来到底new哪个类的对象。

比如点页面的时候,

点注册,这个时候就得建立注册对象,没办法new,只能用反射来判断造哪个对象。

 

2.理解class类并且获取class实例

加载到内存中的类为运行时类,这个运行时类,就是Class的一个实例。

例如,Person类在内存中加载,但类的本身不能直接这么写。后面补个.class。充当了Class的实例。

2.1获取一个Class实例

虽然获取方式不同,但获得的都是Person这个类。所以三个实例都是一个。

方式三,需要完整的类的路径,不同包下的类可能重名。

 Reflection是当前测试类。了解一下就行。

 2.3Class实例对应的结构的说明

2.3.1哪些结构可以有Class实例?

 

 

 

3.类的加载与classLoader的理解。

3.1类的加载

 在加载阶段,生成了一个Class对象,指向方法区。

链接环节,比如说int n=2,这句话。

在链接的时候,做得事是   int   n ,然后给它一个初始值。

在初始化的阶段,才会把2赋给n。

 

一个具体的例子。

 

3.2  ClassLoader的理解(类的加载器)

所以我们前面,获取一个运行时类作为实例,是从类缓存里找到的这些Class对象。

 自顶向下记载,自底向上检查。

引导类加载器:一半加载核心类库。比如String。

扩展类加载器:导入的jar包里的类。

系统类加载器:加载自己定义的类。


 3.2.1使用ClassLoader加载JDBC配置文件。

 

点击扳手图像,进去勾选,不会乱码。

 

方法一:配置文件写在module下。

想在src里用,也可以,加代码路径那,改成   src\\jdbc.properties。多一层目录。

 方法二:配置文件写在src下,因为类创建的时候读资源,只能在此类的src下找配置文件。

方法二是mybatis用的。

 

 

4.创建运行时类的对象。

 这里需要强转。如果变成泛型,不用强转,newInstance识别到了。

 

 这个方法就是空参的,调用一个空参构造器。

5.获取运行时,类的结构

反射能够获得这个注解,生命周期应该为runtime。

注解默认值为hello。

 当注解加到类上面。不想用hello,可以改成hi。

注解可以加在构造器和方法上。

5.1获取属性

 这种方式只能获取子类和父类里的public 声明的属性。

 

 5.2获取 权限修饰符  数据类型 变量名

Modifiers类里,public 为1

所以权限 修饰符那里是int。

 5.3获得所有的方法

 没有获取形参的名字。

 

5.3.1 获取方法的注解。

首先注解必须都是runtime才能被获取。

因为注解可以多重加,所以获取的是一个注解数组。

 5.3.2 获取返回值的类型和权限修饰符

 5.3.3 拿到方法名和形参名。

 5.3.4获取方法抛出的异常

异常可能有多个,所以也要用数组。

 5.4获取构造器结构

构造器获取当前类,没获取父类的,因为用父类的直接super就完事。

 5.5 获取父类,和它的泛型。(有用)

如果只要父类的泛型。actualTypeArguments方法,获得实际类型参数。获取泛型类型。

 5.6获得运行时类实现的接口

getInterfaces方法。

 5.7 获得运行时类所在的包。

getPackage方法。

 5.8 获取注解

 

6.调用运行时,类的结构

6.1调用属性

实例化之后,直接拿出来调用。

想用的属性,设为true。通用的。

 6.2 操作方法

它这个没有setAccessible,少了一句。

 6.2.1调用静态方法。

这里invoke可以写null,因为chazz,识别到showDesc是里面的静态方法。

 6.3调用构造器

一般不用,构造器用来造对象。

获取构造器的时候指明要哪个构造器,即给里面参数类型指明。

 

 7.反射的应用,动态代理

 7.1静态代理举例

静态:编译期间就确定好的。

用的接口的多态,代理类和被代理类都实现同一个接口。

被代理类的对象,用代理类的构造器接收。然后进行操作。 

7.2动态代理的举例。

 

package DynamicProxyLeatn;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author Just Ching
 * @create 2022-01-12 11:44
 */
interface human{
    String getBelief();
    void eat(String food);
}
//被代理类
class superMan implements human{

    @Override
    public String getBelief() {

        return "i can fly";
    }

    @Override
    public void eat(String food) {
        System.out.println(food);

    }
}
//定义一个生产代理类的工厂。
class ProxyFactory {
    //工厂方法声明成静态的,不用声明对象调用,用这个方法返回一个代理类对象。
    public static Object getProxyInstance(Object obj) {
        //obj就是被代理类的对象,Proxy是反射包里的一个类。用它制造一个代理类对象
        //这个方法需要三个参数:1.obj的类加载器,2.obj的接口,
        // 3.InvocationHandler接口实现类的对象,多态。调取代理类里的方法。
        MyInvocationHandler T = new MyInvocationHandler();
        T.bind(obj);//传进被代理类对象。
       return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),T);

    }
}
    class MyInvocationHandler implements InvocationHandler{
       //当我们通过代理类的对象,调用方法a,就会自动调用如下的方法:invoke()
        //接口实现类里写被代理类要执行的方法
        private Object obj;
        //用来接收被代理类。

        public void bind(Object obj) {
            this.obj = obj;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           //加上参数。
            Object ob=method.invoke(obj,args);
            return ob;
        }
    }



public class ProxyTest {
    public static void main(String[] args) {
        superMan superMan=new superMan();
        human proxyInstance = (human) ProxyFactory.getProxyInstance(superMan);
      //不能在这里写suprman, 用man共同的接口实现类的对象   作代理类的对象。。
        String s=proxyInstance.getBelief();
        System.out.println(s);
        /*通过代理类的对象调用方法,然后调用被代理类的方法。*/
        proxyInstance.eat("malatang");
    }



}

7.3动态代理和AOP

即函数式编程。

 面向切面

 中间的方法是不确定的,可替换的,上下两个是固定的通用方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值