[重走长征路]反射学习笔记

这篇具有很好参考价值的文章主要介绍了[重走长征路]反射学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

反射是动态语言的关键,反射机制允许程序在运行期间借助ReflectionApi取得任何类的内部信息,并能直接操作任意对象的内部属性的方法。
概述:java提供的一套api,可以使用api可以在运行时动态的获取指定对象所属的类,创建运行时类的对象,调用指定的结构(属性、方法)
优点: 提高自适应能力降低耦合性, 允许程序控制任何类的对象,无需提前硬编码目标类
缺点:性能低、可读性差
1、面向对象使用反射和不使用反射有何区别
不使用反射我们需要考虑封装性 比如出了某各类后就要考虑某各类中私有结构不能用的情况
使用反射,我们可以调用运行时类中的任意构造器、属性、方法
反射关注的是能不能的问题、封装考虑的是好不好的问题
2、使用场景:两种方法 那种用的多
从开发业务角度来说 我们开发中主要是完成业务代码,对于相关的对象方法调用都是确定的 我们使用非反射的情况多一些。
因为反射体现了动态性 可以在运行时动态的获取对象所属的类,动态的调用相关的方法。所以我们在设计框架的时候会大量使用反射。意味这需要学习框架的源码,那么就需要学习反射
框架=注解+反射+设计模式
3、单例模式的懒汉式中,私有化的构造器!此时通过反射,可以创建单例模式的多个类对象吗?
是的!
4、通过反射,可以调用类中私有化的结构,是否与面向对象思想有冲突 ?是不是Java语言设计存在bug
不存在bug!
封装性是否建议调用内部api的问题,比如 用private生明的结构,意味着不建议调用 如果要调用就修改访问权限
反射:体现的是我们能否调用的问题。反射之所以可以用的前提是因为类的完整结构都加载到内存中,所以就能调用。
class类的理解:
针对编写好的.java源文件进行编译会生成一个或者多个.class字节码文件
我们使用java.exe对指定的.class进行解释运行。这个解释运行的过程,我们需要将.class字节码文件加载到内存中。通过类加载器加载到内存中的.class文件对应的结构即为一个Class实例
比如:加载到内存中的Person类或者String或者User。都可以作为一个一个的实例
运行时类
Class calzz=Person.class;
Class clazz=String.class;
Class clazz=User.class;
运行时类 在内存中会缓存起来
Class是反射的源头
获取Class实例的方法
1、调用运行时类的静态属性:class
Class clazz1=User.class;
2、调用运行时类的对象的Getclass
User u1=new User();
Class clazz2=u1.getClass();
3、调用class的静态方法forName(String className)
String className="com.atguigu2._class.User";
Class clazz3=Class.forName(className);
clazz1==clazz2  true
clazz1=clazz3   true
4、使用类的加载的方法
Class clazz4=ClassLoader.getSystemClassLoader().loadClass("com.at.User");
 clazz1=clazz4;
类加载的过程
过程1
类的装载(loading):将类的class文件读入内存中,并为之创建一个java.lang.Class.此过程为类加载器完成;
过程2
链接(Linking)有三个步骤:
1、验证(Verify):确保加载的类的信息符合jvm规范,例如以cafebabe(魔数)开头,没有安全方面的问题。
2、准备(Prepare):正式为类变量(static静态变量)分配内存并设置类变量默认初始化值的阶段,这些内存都将在方法区中进行分配。
3、解析(Resolve):虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
过程3
初始化
执行类构造器<clinit>()方法的过程
类构造器方法是由编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。
类加载器的作用:
     负责类的加载,并对应于一个Class的实例
分类:
     BootstrapClassLoader:引导类加载器、启动类加载器、
     使用c/c++编写的类加载
     负责加载rt.jar
     继承与ClassLoader的类加载器:
         ExtensionClassLoader:扩展类加载器
         负责加载java.ext.dirs系统属性所指定的加载类库、或者从JDK安装目录的jre/lib/ext目录下记载的内容
         SystemClassLoader、 ApplicationClassLoader:系统类加载器、应用类加载器
         加载我们自定义类的默认加载器
         用户自定义加载器:
         实现应用隔离 同一个类在一个应用程序中加载多份;数据加密
反射的应用: 
  1、创建运行时类对象
1.1如何实现
通过class的实例调用newInstance()方法即可
Class clazz=Person.class;
//创建Person类的实例
Person per=(Person)clazz.newInstance();
1.2想要创建成功,需要满足:
要求运行时类必须提供一个空参构造器
要求空参构造器的访问权限要足够
1.3JavaBean中要求给当期类提供一个公共的空参构造器,有什么用?
场景一:子类对象在实例化时,子类的构造器的首行默认调用父类的空参构造器;
场景二:在反射中经常用来创建运行时类对象,要求各个运行时类都提供一个空参构造器便于我们编写创建运行时类的对象代码
1.4 jdk1.9中newInstance是标示为过时。此时应该使用Constructor类调用newInstance(..);
2获取运行时类的内部结构
2.1获取运行时类内部结构:所有属性、所有方法、所有构造器、
2.2获取运行时类内部结构:父类、接口、包、带泛型的父类、父类的泛型等
3*调用指定的结构,指定的属性、方法、构造器
调用指定的属性
//public int age=1;:
Class clazz=Person.class;
Person per =(Person)clazz.newInstance();
//1获取运行时类指定属性
Field ageField=clazz.getField("age");
//2获取哪个对象的age属性的值
sout(ageField.get(per));
//不仅可以获取 也可以设置属性的zhi
ageField.set(per,2);
-------------------------------
//private String name; 上面操作获取的是public类型的属性的值 关于私有属性值获取值如下:
Class clazz=Person.class;
Person per =(Person)clazz.newInstance();
//通过Class实例调用getDeclaredField(String fieldName)获取运行时类的指定名称的属性
Field nameField = clazz.geeDeclaredField("name");
//确保此属性是可以访问的
nameField.setAccessible(true);
//set给其属性赋值 get获取其属性的值
nameField.set(per,"Tom");
sout(nameField.get(per));
----------------------------------
此可以作为调用指定属性的通用步骤
****************** 调用指定的方法***********
// private String showNation(String nation,int age){}
Class clazz=Person.class;
Person per =(Person)clazz.newInstance();
1、通过Class的实例调用geeDeclaredMethod 方法,获取指定的方法
Method nationMethod = clazz.geeDeclaredMethod("showNation",String.class,int.class);
2、确保此方法可以访问到
nationMethod.setAccessible(true);
3、传参调用方法 可以获取返回值  invoke的返回值就是方法shownation的返回值 如果shownation返回值是void 则invoke返回值是null
Object obj=nationMethod. (per,"chn",10);
*****************************************
***************调用指定的构造器***********
// private Person(String name  ,String int){}
Class clazz=Person.class;
1、通过Class实例调用geeDeclaredConstructor(参数) 获取指定参数类型的构造器
Constructor constructor=clazz.geeDeclaredConstructor("showNation",String.class,int.class);
2/确保此构造器可以访问
constructor.setAccessible(true);
3/返回运行时类的实例
Person per=constructor.newInstance("Tom",12);

文章来源地址https://www.toymoban.com/news/detail-499791.html

到了这里,关于[重走长征路]反射学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java动态代理、反射

    动态代理就是无侵入式的给代码增加新的功能,通过接口保证后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法,代理里面就是对象要被代理的方法。 因为一个对象觉得自己身上的功能太多,就会将一部分功能代理出去,对象中什么方法想要被代理,在代

    2024年02月11日
    浏览(50)
  • Java反射和动态代理

    反射允许对封装类的成员变量、成员方法和构造方法的信息进行编程访问 成员变量:修饰符、名字、类型、get/set值 构造方法:修饰符、名字、形参、创建对象 成员方法:修饰符、名字、形参、返回值、抛出的异常、获取注解、运行方法 获取class对象 Class.forName(“全类名”

    2024年02月03日
    浏览(56)
  • C# 通过反射以及动态调用方法

    有时候需要通过反射以及动态调用的办法去调用已知的实例的方法,感觉还是挺巧妙的。以下主要记录通过反射以及动态的调用方法。 运行结果如下图所示: 总结:在已知方法的情况下,还是动态调用比较方便,但是要注意异常处理,毕竟这属于特殊情况,编译执行前不会

    2024年02月07日
    浏览(51)
  • 【C#】反射机制,动态加载类文件

    【C#】编号生成器(定义单号规则、固定字符、流水号、业务单号) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器(开始日期、结束日期) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129040663 【C#】组件化开发,调用dll组件方法 本文链接

    2024年02月11日
    浏览(70)
  • 【JAVA】单元测试、反射、注解、动态代理

    @Test 测试方法 @Before 用来修饰实例方法,该方法会在每一个测试方法执行之前执行一次。 @After 用来修饰实例方法,该方法会在每一个测试方法执行之后执行一次。 @Before Class 用来静态修饰方法,该方法会在所有测试方法之前只执行一次。 @After Class 用来静态修饰方法,该方法

    2024年02月11日
    浏览(42)
  • C# 运用(codeDom和反射技术)动态编译dll ,动态调用

          在软件运用工程中,往往会根据各种各样,花样百出的需求来设计软件,在最近的项目中无意中,我就遇到了一个需求,据说是,客户要动态编译dll ,我“滴个乖乖”,这是要逆天啊! 话不多说,直接来点干货。 简单分享一下个小demo: 1.运用codeDom技术实现动态程序集

    2024年02月13日
    浏览(39)
  • gin通过反射来执行动态的方法

    在gin中,可以通过反射来执行对应的方法。下面是一个示例: 在这个示例中,我们定义了一个 UserController 结构体,并在结构体中定义了 GetUser 方法和 queryUser 方法。 GetUser 方法用于处理请求并返回用户数据, queryUser 方法用于查询用户信息。 在主函数中,我们创建了 UserCon

    2024年02月14日
    浏览(47)
  • C# Assembly 反射动态加载程序集(动态加载Dll)Demo

    No1、本Demo 定义了一个接口IserviceToolFrame,接口中有一个方法Run。 No2、在另外两个工程中,分别定义两个类serviceToolCatComplete、serviceToolDogComplete实现接口IserviceToolFrame。 No3、控制台程序通过动态加载Dll的方式去调用IserviceToolFrame的实例,输出不同的内容。代码如下: 动态加载

    2024年02月15日
    浏览(56)
  • 动态规划学习笔记

    一般形式是求最值,核心是穷举。 首先,虽然动态规划的核心思想就是穷举求最值,但是问题可以千变万化,穷举所有可行解其实并不是一件容易的事,需要你熟练掌握递归思维,只有列出正确的 「状态转移方程」 ,才能正确地穷举。而且,你需要判断算法问题是否 具备「

    2024年01月16日
    浏览(35)
  • 学习笔记——动态规划(全)

    递推问题包括动态规划,动态规划一定是递推,递推不一定是动态规划。 动态规划是一种决策性的问题,是在状态中做最优决策的一种特殊递推算法,通常的问法包括求最大最小值等,而递推可能还会包括求种类数等问题。 递推是一种算法,用来解决一类特殊的问题,而递

    2024年03月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包