js java 反射机制_java 类加载机制和反射机制

一.类的加载机制

jvm把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成jvm可以直接使用的java类型的过程。

(1)加载

将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口。

(2)链接 将java类的二进制代码合并到jvm的运行状态之中的过程。

验证:确保加载的类信息符合jvm规范,没有安全方面的问题。

准备:正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。

解析:虚拟机常量池内的符号引用替换为直接引用的过程。(比如String s ="aaa",转化为 s的地址指向“aaa”的地址)

(3)初始化

初始化阶段是执行类构造器方法的过程。类构造器方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。

当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先初始化其父类的初始化

虚拟机会保证一个类的构造器方法在多线程环境中被正确加锁和同步

当访问一个java类的静态域时,只有真正声明这个静态变量的类才会被初始化。

二.java反射机制

通俗地说:反射就是将Student类中的方法、成员变量、构造方法,抽象出来可以让Class的对象单独进行访问。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

d43950625a9f63b4b615e4ea603f79cc.png

1、获取Class对象的三种方式

(1)通过调用forName(String className),注意className的格式为:包名.类名获得Class对象。

7c79d8e7ebe7c13779b00c3a656dc843.png

(2)通过类获取Class对象,String.class、int.class这些字节码是Class类的对象。

(3)通过类的对象获取Class对象。

1 public static void getClass1() throwsClassNotFoundException {2 //获取Class的方法3 //正射

4 Student stu=newStudent();5 //第一种(优先选择):传的是包名.类名,通过包名和类名获得反射Class

6 Class cl1=Class.forName("day20.Student");7 //第二种:通过类来获取Class对象

8 Class cl2=Student.class;9 //第三种:通过对象获取Class对象

10 Student s=newStudent();11 Class cl3=s.getClass();12 //判断三种方法是否是同一个Class对象

13 System.out.println(cl1==cl2);14 System.out.println(cl2==cl3);15

16 }

2、获取构造方法

(1)获取公开的构造方法

671e178295acdf329d24b40bdec53839.png

(2)获取所有的构造方法

主要为调取Student类中的私有方法。注意:不能获得Student类的父类Human中的构造方法。

d44f310df4abdb37c8c2f5ce069fad7f.png

(3)调用特定的构造方法

无参构造和有参构造方法Constructors1.newInstance();//实例化获取的类

d3787356c278cebe39b7b08cf09207c2.png

私有构造方法的调用,要注意要设置其访问权限Constructors1.setAccessible(true)。

1 public static void getConstruction() throwsException {2 //获取构造方法

3 Class cl=Class.forName("day20.Student");4 System.out.println("==========公开的构造方法==========");5 //获得公开的构造方法

6 Constructor[] cons=cl.getConstructors();7 for(Constructor con:cons) {8 System.out.println(con);9 }10 System.out.println("==========所有的构造方法==========");11 //获得所有的构造方法

12 Constructor[] constructors=cl.getDeclaredConstructors();13 for(Constructor con:constructors14 ) {15 System.out.println(con);16 }17 System.out.println("==========调用构造方法==========");18 //调用无参构造方法

19 Constructor constructors1=cl.getConstructor();20 Student student=(Student)constructors1.newInstance();21 //调用有参构造方法

22 Constructor constructors2=cl.getConstructor(String.class);23 Student student1=(Student) constructors2.newInstance("英语");24 //调用私有构造方法

25 Constructor constructors3=cl.getDeclaredConstructor(int.class);26 constructors3.setAccessible(true);//因为是私有化的方法,所以要设置访问权限

27 Student student2=(Student) constructors3.newInstance(2);28 }

执行结果:

==========公开的构造方法==========

public day20.Student(java.lang.String)

public day20.Student()

==========所有的构造方法==========

private day20.Student(int)

public day20.Student(java.lang.String)

public day20.Student()

==========父类的构造方法==========

无参构造方法

有参构造方法英语

私有构造方法2

3、获取方法

私有属性的调用,要注意要设置其访问权限Constructors1.setAccessible(true)。

1 private static void getMethod1() throwsException {2 Class cl=Class.forName("day20.Student");3 //获取所有公开的方法,包括Object中的类

4 Method[] method=cl.getMethods();5 for(Method m:method6 ) {7 System.out.println(m.getName());8 }9 //获取本类中所有的方法,不包括父类和eObject

10 System.out.println("==========私有方法==========");11 Method[] methods=cl.getDeclaredMethods();12 for(Method ms:methods13 ) {14 System.out.println(ms.getName());15 }16 //调取方法

17 System.out.println("==========调取特有方法==========");18 //获取非静态的无参方法

19 Method method1=cl.getMethod("eat");20 //获取Student类的成员

21 Constructor constructor=cl.getConstructor();22 Student student=(Student)constructor.newInstance();23 method1.invoke(student);24 //获取非静态含参方法

25 Method method2=cl.getMethod("study", String.class);26 method2.invoke(student,"物理");27 //获取静态无参方法

28 Method method3=cl.getMethod("sleep");29 method3.invoke(null);30 //获取静态含参方法

31 try{32 Method method4=cl.getMethod("saveMoney", double.class);33 method4.setAccessible(true);34 method4.invoke(null,100.0);35 }catch(NoSuchMethodException e){36 e.getMessage();37 }catch(Exception e){38 e.getMessage();39 }40

41 }

执行结果:

getName

setName

sleep

study

eat

setMoney

getMoney

getAge

setAge

getSex

setSex

wait

wait

wait

equals

toString

hashCode

getClass

notify

notifyAll

==========私有方法==========

getName

setName

sleep

study

eat

saveMoney

setMoney

getMoney

getAge

setAge

==========调取特有方法==========

吃饭

学习物理

睡觉

4、获取属性

1 private static void getAttribute1() throwsException{2 Class cl=Class.forName("day20.Student");3 //获取所有属性

4 Field[] fields=cl.getFields();5 for(Field field:fields6 ) {7 System.out.println("属性值有:"+field.getName());8 }9 //获取私有化属性

10 Field field=cl.getDeclaredField("money");11 field.setAccessible(true);12 //获取Student类的成员

13 Constructor constructor=cl.getConstructor();14 Student student=(Student)constructor.newInstance();15 student.setMoney(100);16 System.out.println("通过对象.方法进行属性赋值:"+student.getMoney());17 field.set(student,200);18 System.out.println("通过Field对象.方法进行赋值:"+student.getMoney());19 }

执行结果:

属性值有:name

通过对象.方法进行属性赋值:100.0

通过Field对象.方法进行赋值:200.0

Student类和父类

1 packageday20;2

3 public class Student extendsHuman{4 publicString name;5 intage;6 private doublemoney;7

8 publicStudent() {9 System.out.println("无参构造方法");10 }11 publicStudent(String subject) {12 System.out.println("有参构造方法"+subject);13 }14

15 private Student(inti) {16 System.out.println("私有构造方法"+i);17 }18 publicString getName() {19 returnname;20 }21 public voidsetName(String name) {22 this.name =name;23 }24 public intgetAge() {25 returnage;26 }27 public void setAge(intage) {28 this.age =age;29 }30 public doublegetMoney() {31 returnmoney;32 }33 public void setMoney(doublemoney) {34 this.money =money;35 }36

37 public voideat(){38 System.out.println("吃饭");39 }40

41 public voidstudy(String subject){42 System.out.println("学习"+subject);43 }44

45 public static voidsleep(){46 System.out.println("睡觉");47 }48

49 private static void saveMoney(doublemoney){50 System.out.println("存款"+money);51 }52 }53

54

55 packageday20;56

57 public classHuman {58 privateString sex;59 publicHuman(){60

61 }62

63 private Human(inti){64

65 }66

67 publicString getSex() {68 returnsex;69 }70

71 public voidsetSex(String sex) {72 this.sex =sex;73 }74 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/526819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lambda 流 peek java_JDK8 流与λ表达式

λ表达式什么是λ表达式λ表达式有三部分组成:参数列表,箭头(->),以及一个表达式或者语句块。public int add(int x, int y) {return x y;}转换为λ表达式(int x, int y) -> x y;去除参数类型(x, y) -> x y;无参 以及 只有一个参…

理解java虚拟机工作后了解吗_JAVA入门到再次入门——深入理解JAVA虚拟机(二)|七日打卡...

前言为什么叫做入门到到再次入门请参考前一篇或个人博客,在此不再赘述,嗯哼,了解了JVM的基本运行流程以及内存结构,算是初步认识了JVM,跟着课本往前走,继续了解根据JVM的内存模型探索java当中变量的可见性以…

java访问错误404_如何解决 Java web 项目中的 404 错误

在使用 Tomcat 进行 Java Web 开发的时候,经常会遇到以下 HTTP 404 错误:错误代码为 HTTP 404(未找到),描述信息是:“The origin server did not find a current representation for the target resource or is not willing to di…

java double 的精度_Java Double的精度问题

Java.text类 DecimalFormatjava.lang.Objectjava.text.Formatjava.text.NumberFormatjava.text.DecimalFormatvoid setMaximumFractionDigits(int newValue) 设置某个数的小数部分中所允许的最大数字位数。void setMinimumFractionDigits(int newValue) …

java餐饮管理系统图片,基于jsp的酒店餐饮管理系统-JavaEE实现酒店餐饮管理系统 - java项目源码...

基于jspservletpojomysql实现一个javaee/javaweb的酒店餐饮管理系统, 该项目可用各类java课程设计大作业中, 酒店餐饮管理系统的系统架构分为前后台两部分, 最终实现在线上进行酒店餐饮管理系统各项功能,实现了诸如用户管理, 登录注册, 权限管理等功能, 并实现对各类酒店餐饮管…

php 验证码一直不对,ThinkPHP验证码老是出错怎么办

ThinkPHP验证码老是出错的解决办法:1、找到服务器php配置文件php.ini在网站根目录下建一个info.php文件。例如:D:\wwwRoot\wp 这个是网站的根目录,在此目录下,新建一个txt文档,输入如下代码:然后另存为info…

如何在php中插入数据并修改,php怎么同时向2张表里插入数据

情况是这个样子的:我要做一个发消息的表,因为接受人可能是多个,所以又给接收人一单独的表,(这种方案好还是全部都放到一张表里好点呢?)2张表的字段如下:message_id是第一张表的主键,如果收件人有…

java设计模式之道文字版,Java Web设计模式之道 PDF

资源名称:Java Web设计模式之道 PDF第一部分 仙人指路——设计模式简介第1章 设计模式概述1.1 设计模式是什么1.2 软件设计模式的发展历程1.3 作者阐述软件设计模式的主要方式第二部分 设计红宝书——设计模式原则详解第2章 设计原则之开闭原则2.1 何谓开闭原则2.2 …

matlab变量由非标量,matlab中的if语句

有条件性地执行语句语法if expressionstatementsend描述MATLAB计算表达式,如果产生一个逻辑真或者非零结果,然后就执行一条或者多条MATLAB命令语句。当有嵌套if时,每一个if必须和一个相应的end匹配。当你在if语句里面嵌套使用else if或者else…

rodbc 连接oracle,R語言 使用RODBC連接oracle數據庫

使用R語言有多種包可以連接oracle數據庫,我今天在這里講一下使用使用RODBC連接oracle數據庫。1. 如果你的本地是windows系統的話,你需要安裝oracle客戶端。2. 然后需要在ODBC管理者界面配置你要進行連接的數據庫數據及使用的驅動等信息。如下圖所示&…

oracle实验七 答案,Oracle表的常用查询实验(七)

Oracle表的常用查询实验(七)1.问题描述:有一个商品信息表,该表反应了各种商品的销售情况,一个产品是按照gid和gname两个字段来区分的,一个产品可能会有多个型号。create table T_Goods(Id int primary key,GId varchar2(10) not n…

oracle ogg00423,【案例】Oracle报错PLS-00378 PLS-00439产生原因和MOS官方解决办法

【案例】Oracle报错PLS-00378 PLS-00439产生原因和MOS官方解决办法时间:2016-11-12 21:31 来源:Oracle研究中心 作者:代某人 点击:次天萃荷净PLS-00378此版本的PL / SQL编译单元无效原因:编译单元是一个文件,其中包含的PL / SQL传递给编译器的源代…

linux系统如何备份系统软件,Linux折腾记(十三):我该如何备份系统

在前面的一些文章中,我反复提到经常会把系统搞崩溃,所以备份系统就是一件不容忽视的事情。由于Linux系统本身的优越性,系统的备份和还原还是比较容易的。主要表现在以下方面:1.Linux系统所有的数据都以文件的形式存在,…

linux kset subsystem 3.10内核,Kobject、Kset 和 Subsystem

2014年5月12日Kobject 、Kset 和 Subsy stem - 海王 - 博客园http://www.doczj.com/doc/93b5b6113b3567ec112d8a49.html/leav en/archiv e/2010/04/24/1719191.html 4/8件(2)4. Linux input 子系统 io 控制字段(2)5. linux 内核定时器 tim er_list 详解(2) (2)把kobject 的 kse…

linux 自定义vi dd,Vim常用命令及配置方案

几句话很久之前就接触到vim,初学那阵觉得vim很酷炫,但确实对新手不是很友好。我也就简单看了下基本操作就上手了,但又不是长期在vim下工作,这就导致了每一次重新使用vim都要再去回温下基本操作,很是难受,所…

linux指纹登录实现原理,指纹识别技术原理与基于Linux系统的指纹识别门禁系统设计...

指纹作为人体的身体特征,具有唯一性、稳定性和不易盗用等特点。随着指纹识别理论逐渐成熟、指纹采集工具这一难题得到解决,指纹识别已经成为目前最广泛应用的生物识别之一,逐渐取代了传统的认证识别方式,广泛应用于金融、公安、证…

linux wps历史版本下载,WPS Office 2019 For Linux 11.1.0.9604版携新更新发布下载

WPS Office 2019 For Linux 11.1.0.9604版本发布了,仅支持64位计算机,提供Deb和Rpm格式软件包下载。更新详情1、WPS公共:优化界面绘制相关api的调用效率。适配ibus和fcitx框架的输入法,解决无法输入中文,预输入显示等问…

Linux双独立显卡SLI,玩点新奇的 双显卡给你不同的“SLI”效果

显卡老是千篇一律的常规测试对于我们这些测试人员来说早就已经没有什么意思了,无非就是跑分,超频后跑分,拷机等等一些测试项目,常看我们测试的玩家应该也知道同芯片显卡除非是频率的差别非常大才会有较为明显的性能差距体现出来&a…

android win10 驱动安装失败,解决在win10系统下小米手机驱动安装失败的具体步骤...

随着系统的升级越来越快,对于许多用户的系统都已经升级到win10系统了,win10系统在给用户带来方便的同时,有时候也会遇到一些小麻烦,比如说对于最新的Window10正式版系统而言,基本主流的手机驱动都能自动检测安装。不过…

z3735f android x86,英特尔的Atom Z3735F分析 全文总结_台电 X80HD_平板电脑评测-中关村在线...

硬件配置:英特尔64位提供性能保证台电X80HD双系统使用Intel Atom Z3735F四核处理器,最高睿频可达1.83GHz,其采用64位X86架构,搭载最新一代睿频加速技术,并拥有四核四线程,支持多任务同时处理。英特尔的Atom…