java 反射 内存_Java内存到反射入门

Java内存到反射入门(一)

初识Java内存

平常我们最常提到的的JAVA分区是这三个分区

033ea5706ea25e4dbdf17f42476360dd.png

其中方法区是一个特殊的堆,功能如图上所示。

初识反射:框架设计的灵魂

反射的功能:将类的各个组成部分封装为对象,并在程序运行的过程中可以调用它们。

Java代码的三个阶段

我们平时书写的java代码,从书写完成到内存中执行主要经历了三个阶段:Source 源代码阶段,class类对象阶段,Runtime运行时阶段。下图以一个简单的Person类来举例说明。

462e4492d93b5ded507dd87f24111158.bmp

第一阶段:Source源代码阶段

首先,我们编写好了一个Person类的代码,它由成员变量,构造方法,成员方法三部分组成。

public class Person{

private String name;

private int age;

public Person(){}

public void eat(){}

}

此时它是一个Person.java文件。还不能运行,接着我们要用javac命令编译它,使生成一个Person.Class字节码文件。

43c346428c2126b56a4f1f7d9724211b.png 这个文件我们并不能看懂,其实里面主要包含三部分内容:成员变量,成员方法和构造方法,还有一些诸如包名的信息。

至此,源代码和字节码都是以文件的形式储存在硬盘上的,还未进入内存,此阶段我们称之为Source源代码阶段。

第二阶段:Class类对象阶段

要想由第一个阶段进入第二个阶段,要经过一个加载的过程。由类加载器ClassLoder将class文件加载到内存中,并生成该类的class类对象。class类对象是来描述字节码文件的,字节码文件被封装为三大部分:

1.成员变量被封装为Field对象,并用Filed[]存储。

2.构造方法被封装为Constructor对象,并用Constructor[]存储。

3.成员方法被封装为Method对象,并用Method[]存储。

这样的封装就是反射机制,经过了这样的封装后,我们就可以在程序运行的过程中来操作这些对象了。即获取,修改变量和执行方法等。

举个栗子:在IDEA等IDE中,写如下一段代码:

//定义了一个字符串变量,并尝试调用它自带的方法

String str = "abc";

str.

在按下str后面这个.后,IDEA会提示许多的方法。

cefe9436cc929ff558912dce55a87ae4.png 那么为什么IDEA会提示这些方法呢?其实内部就是反射机制。 定义了一个String变量后,则字符串的字节码文件就会被加载进内存。在内存中就有了String的class类对象,里面封装了Method[]存储了所有String的方法。所以只要挨个显示一下就可以了。

第三阶段:Runtime运行时阶段

第二阶段通过创建对象等操作就会进入第三阶段,创建对象时就会根据这个class类对象创建一个真正的Person对象。

获得class类的三种方法

Class.forName("全类名"):将字节码文件加载进内存,返回Class对象 * 多用于配置文件,将类名定义在配置文件中。读取文件,加载类

//如获取Person类的.Class文件

Class a = Class.forName("Domain.Person");//Domian是Person类所在包

类名.class:通过类名的属性class获取,该方法多用于参数的传递。

Class a = Person.calss;

对象.getClass():getClass()方法在Object类中定义着,该方法多用于对象的获取字节码的方式

Person person = new Person();

Class a = person.getClass();

Tip:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

//采用多种方式得到.Class文件

Class a = Class.forName("Domain.Person");

Person person1 = new Person();

Person person2 = new Person();

Class b = person1.getClass();

Class c = Person.class;

Class d = person2.getClass();

//不管以哪种方式得到的.Class类,只要是Person类的,那就是一样的。

System.out.println(a==b); //true

System.out.println(c==b); //true

System.out.println(a==c); //true

System.out.println(a==d); //true

Class类的用法

在熟悉了Class类的获取方法后,自然要熟悉其用法。

//以下是测试用的Person类

public class Person {

private String name;

private int age;

private int id;

public Person() {

}

public Person(String name, int age, int id) {

this.name = name;

this.age = age;

this.id = id;

}

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 int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

@Override

public String toString() {

return "Person{" +

"name='" \+ name \+ '\\'' +

", age=" \+ age +

", id=" \+ id +

'}';

}

}

用法一:获取类的名字

方法有两个:

String getName(); //返回类的包名+类名

String getSimpleName();//获取简单类名

Class c1 = Person.class;

System.out.println(c1.getName()); //该方法获取类的全名,输出Domain.Person

System.out.println(c1.getSimpleName());//该方法获取类的简单名,即Person

用法二:获得类的属性

方法有四个:

Field[] getFields() :获取所有public修饰的成员变量

Field getField(String name) 获取指定名称的 public修饰的成员变量

Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符

Field getDeclaredField(String name)

c7c1db92c02fb922988de54ecf86f8e8.png

用法三:获得类的方法

方法有四个:

Method[] getMethods() ;

Method getMethod(String name, 类>... parameterTypes) ;

Method[] getDeclaredMethods() ;

Method getDeclaredMethod(String name, 类>... parameterTypes) ;

45aceba3d3fb027b476f85e5f80856d8.png 注意第一个方法会获取包括本类和父类的所有public方法。 第二个方法只会获取本类的所有方法,包括private的,不包括父类的方法。

6a908bec4ad8d863092900ec7ff0cd46.png 获取指定方法的第一个参数是方法的名称,第二个参数是要获取的方法的参数类型,如setName(String name);函数,参数是String,则此处写String.Class;

用法四:获得构造器(构造方法)

有四种方法:

获取构造方法们

Constructor>[] getConstructors()

Constructor getConstructor(类>... parameterTypes)

Constructor getDeclaredConstructor(类>... parameterTypes)

Constructor>[] getDeclaredConstructors() ;

ce5352a2c7abac53c07b265ea9345b17.png

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

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

相关文章

stopping hbasecat: /tmp/hbase-elastic-master.pid: 没有那个文件或目录

stop-hbase.sh 挂了。。。 原因其实也简单,默认情况下hbase的pid文件保存在/tmp目录下,/tmp目录下的文件很容易丢失,不知道为什么他不会自动创建一个非临时目录,大概是因为权限不好控制,需要手动来? 修改为…

服务容错模式

0.背景 随着服务框架和服务治理体系的逐步成熟,服务化已成为系统设计的趋势。随着业务复杂度的增加,依赖的服务也逐步增加,出现了不少由于服务调用出现异常问题而导致的重大事故,如: 1)系统依赖的某个服务发…

从大学到结婚,我和小云的这13年

看了龙哥的文章,感触很深,我有好几次想写一篇我和小云的文章,记录下自己和小云这些年一起经历的很多事情,但是每每都停下来去做了觉得更重要的其他事情,这次真的决定要写了。我和小云是大学同学,我们大一认…

xshell如何运行java_利用Xshell往应用服务器上部署项目

1.首先查询中间件的进程Idps -ef|grep ./startapusic2.然后杀掉进程kill -9 16833.再次查询进程,查看是否关闭成功,如果没有/bin目录下的东西了说明关闭成功4.利用ls查看当前路径下的文件5.启动中间件./startapusic6.如果显示地址已在使用,则…

详解Linux内核在arm上的启动过程

Linux内核加载过程通常,Linux内核都是经过gzip加载过之后的映像文件。bootloader复制压缩内核到内存空间。内核自解压。运行内核。编译完成的Linux内核存放在哪里?./vmlinux elf格式未压缩内核。arch/arm/boot/compressed/vmlinux 压缩以后的elf格…

java 数据库 properties_原生Java读取properties连接数据库

将数据库的驱动、url、用户名、密码等信息以键值对的形式存放在properties文件中,工具类初始化时从配置文件中读取所要连接数据库的信息。当需要更改连接的数据库时,只需要更改配置文件即可,而不必改写工具类的代码。1.在项目中创建一个prope…

【谱聚类算法总结】

前言:以前只是调用过谱聚类算法,我也不懂为什么各家公司都问我一做文字检测的这个算法具体咋整的,没整明白还给我挂了哇擦嘞?讯飞还以这个理由刷本宝,今天一怒把它给整吧清楚了,下次谁再问来!说…

嵌入式的汉字原来是这样显示的?

摘要:LCD是嵌入式常见设备,如何在LCD上显示汉字和英文?矢量字体和点阵字体有何不同?同一个字符为何有多种编码?GB2312、GB18030指什么?他们之间有关系吗?嵌入式设备如何支持多国语言&#xff1f…

查看数据库、表、索引的物理存储情况

在管理、维护数据库时,经常需要查看数据库文件、日志文件所占用的磁盘空间,以及磁盘还剩下的磁盘空间,你可以通过下面几种方面查看数据库文件详细情况:1: 是通过远程连接(或VPN)连接到数据库服务器,直接去查…

Spring简化Java开发_spring如何简化java开发

1、spring简介Spring的主要目的是用来替代更加重量级的企业级的java技术2、spring如何简化java开发1)基于POJO的轻量级和最小侵入性编程;2)通过依赖注入和面向接口实现松耦合;3)基于切面和惯例进行声明式编程;4)通过切面和模板减少样版式代码…

Linux 应用调试神器- ASan

今天有小伙伴跟我他的程序崩溃了要怎么办,刚好我最近做项目使用到这个神器,做应用开发的同学可以看看,可以在C/C上配置使用。不过这仅限于调试,如果你是发布版本,一定要把这个功能关闭。当然,这是我实操的结…

asp.net验证提示美化效果

前段时间做了个ymPrompt提示效果的验证控件,ymPrompt是弹出提示的。弹出提示会增加无畏的鼠标点击动作。前段时间看到园里有位高手写了个纯cssjs的一个效果,我把它和asp.net验证控件结合起来,用这位高手写的效果做为asp.net难控件的提示效果。…

在Linux内核使用Kasan

昨天的文章发出来后,有同学在群里说内核也可以使用这个工具,所以再转发一篇wowo网站的文章,希望对大家有帮助。Linux 应用调试神器- ASan1. 前言KASAN是一个动态检测内存错误的工具。KASAN可以检测全局变量、栈、堆分配的内存发生越界访问等问…

跟韦老师聊了一个深夜

自从尚明从韦老师那边离职后,我已经很难得到韦老师的消息了,有时候我也想过去看下他,但是也很难抽的开时间。而且,我们两都挺技术的,如果见面后不知道聊什么,会不会有点尴尬。😄上面那个回复是我…

大厂不是铁饭碗

最近的事情有点多前段时间一个以前的朋友,买房找我咨询,问我恒大的房子能不能买,我当时没有给出明确的回复,但是也说了自己的看法。近些年房子越来越贵,我是从15年开始接触房子,不过我从没有想过靠房子来赚…

使用valgrind检测内存问题

valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。1valgrind安装可以到官网下载最新的源码包:valgrind官网下载,也可以直接使用 c_utils/debug/valgrind 目录提供的 valgrind-3.13.0.tar.bz2 源码包。首先解压源码包tar xjf valgri…

项目中cxf和weblogic整合时报错的问题

GJYW项目使用的weblogic版本是10.3.6,cxf使用的版本是3.1.4 在将项目部署到weblogic服务器上时就会报错,通过下面的方式可以解决weblogic和cxf框架在一起报错的问题(解决了本项目报错的问题,未必全部适用):…

下周开幕!给深圳的嵌入式和电子工程师准备的嘉年华来了

我和电子圈老江认识了很久,应该是2012年,小龙第一次参加电子圈年会,那年他年会中奖的奖品送给我。后来,我也加入了电子圈的QQ群,早些年的时候,大家都喜欢在QQ群聊天,后来才慢慢转到微信群。老江…

AS3.0中的显示编程(末篇)-- 滤镜(下)

剩下的三种滤镜,因为我自己也不是很懂矩阵啊这些的,只能做些简单的范例和说明了,抱歉!颜色矩阵滤镜、卷积滤镜、置换图滤镜这三种滤镜只能通过AS代码实现。如果说上面的六种滤镜,只是在原图的基础上做些简单的修改&…

这几个朋友,我记得

‍‍昨天的中秋节是在公司加班度过的,末了,在群里看到有人说要是今天还有人加班的话,那他一定是真正的卷王,好了,我是那个中秋节加班的卷王。早上打车去公司,快到公司楼下的时候,司机师傅跟我说…