java基础-反射、动态代理

参考 https://www.cnblogs.com/whgk/p/6122036.html

https://blog.csdn.net/huangliniqng/article/details/88554510

https://blog.csdn.net/sinat_38259539/article/details/71799078?depth_1-utm_source=distribute.pc_relevant_right.none-task-blog-BlogCommendFromMachineLearnPai2-1&utm_source=distribute.pc_relevant_right.none-task-blog-BlogCommendFromMachineLearnPai2-1

https://www.jianshu.com/p/9bcac608c714

https://cloud.tencent.com/developer/article/1461796

https://www.liaoxuefeng.com/wiki/1252599548343744/1264804593397984

反射和动态代理是非常重要的基础概念,可以说,诸多框架的实现都依赖了这两种手段,这篇博客,博主会来学习总结一下反射和动态代理的相关知识,写博客也是为了知识储备,可以不记得细节,但是用到了,要记得这么个东西,要知道怎么查找材料

jvm虚拟机在创建对象的时候,会先把这个类对应的class文件加载到方法区中,然后在堆上创建class对象(字节码对象),并由此字节码对象来创建具体的对象。所以,字节码对象中会包含对应类内部的属性、构造和方法等,通过反射技术,我们可以直接获取这些属性,调用该类的方法(包括私有属性和私有方法)。

一 、什么是反射?

    在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。

所以根据之前的介绍,既然class对象中包含我们想要的东西,那么反射自然是依赖于class对象的

获取一个类对应class对象的方式有三种:

       1、Class clazz1 = Class.forName("全限定类名");  //通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。

       2、Class clazz2  = Person.class;    //当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。

       3、Class clazz3 = p.getClass();    //通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段 

    有了字节码文件对象才能获得类中所有的信息,我们在使用反射获取信息时,也要考虑使用上面哪种方式获取字节码对象合理,视不同情况而定。下面介绍Class类的功能。

对class对象的常见操作API如下

二、反射机制能够获取哪些信息?Class类的API详解。

    2.1、通过字节码对象创建实例对象

 2.2、获取指定构造器方法。constructor 如果没有无参构造,只有有参构造如何创建实例呢?看下面

      总结上面创建实例对象:Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了,可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance("张三",20)方法创建对象

      获取全部构造方法

  

    2.3、获取成员变量并使用  Field对象

         获取指定成员变量

         Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取,通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值

        获取全部成员变量

    2.4、获得方法并使用  Method

        Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法,如果为私有方法,则需要打开一个权限。setAccessible(true);

        用invoke(Object, Object...)可以调用该方法,

        跟上面同理,也能一次性获得所有的方法

    2.5、获得该类的所有接口

         Class[] getInterfaces():确定此对象所表示的类或接口实现的接口

         返回值:接口的字节码文件对象的数组

    2.6、获取指定资源的输入流

         InputStream getResourceAsStream(String name)  

         return:一个 InputStream 对象;如果找不到带有该名称的资源,则返回 null

         参数:所需资源的名称,如果以"/"开始,则绝对资源名为"/"后面的一部分。

 

动态代理

代理模式,即代理对象代替被代理对象执行任务,

一种设计模式,常见的设计模式共23种,会有专门的博客去介绍,这里不细说

提到动态代理,也提一下静态代理,“动”与“静”的区别,就是是否运行时

动态代理在运行时执行被代理对象的任务,而静态代理是写死的。

这里大致解释一下动态代理的价值所在,我们普通调用执行的方式为new Student()对象,然后对象调用方法,弹有了动态代理,我们可以不必自己创建对象调用方法,而是换作代理对象来代替原对象执行,那么我们就可以对任务的执行进行干预,比如,方法执行前我们添加一个事务操作,并且根据方法的执行状态我们可以判断是否要回滚事务。日志记录的也是运行时状态,还有耳熟能详的spring面向切面编程AOP。

  • 日志集中打印
  • 事务
  • 权限管理
  • AOP

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 设计模式遵循的原则有6个: 1、开闭原则(Open Close Principle)   对扩展开放,对修改关闭。 2、里氏代换原则(Liskov Substitution Principle)   只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。 3、依赖倒转原则(Dependence Inversion Principle)   这个是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle)   使用多个隔离的借口来降低耦合度。 5、迪米特法则(最少知道原则)(Demeter Principle)   一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle)   原则是尽量使用合成/聚合的方式,而不是使用继承。继承实际上破坏了类的封装性,超类的方法可能会被子类修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值