Java变量在内存中的存储
Java变量在内存中的存储
以下探究成员变量和局部变量在内存中的存储情况。
package com.my.pac04;
/**
* @author Summerday
* @date 2019/12/1 13:05
*/
public class ValStoreTest {
public static void main(String[] args) {
//分别创建两个Value类的实例,val0和val1
Value val0 = new Value();
Value val1 = new Value();
//修改val0的num值
val0.num = 5;
System.out.println("val0's num = " + val0.num);//val0'num =5
System.out.println("val1's num = " + val1.num);//val0'num =0
//直接使用类调用类变量
Value.staticNum = 10;
//使用实例对象调用类成员变量,不建议使用
//val0.staticNum = 10;
System.out.println("val0's staticNum =" + val0.staticNum);//10
System.out.println("val1's staticNum =" + val1.staticNum);//10
}
}
class Value {
public int num;//实例变量
public static int staticNum;//类变量
}
成员变量
上面提到成员变量分为实例变量和类变量。这两者在内存中的存储形式又是如何呢?
class Value {
public int num;//实例变量
public static int staticNum;//类变量
}
实例变量
Value val0 = new Value();
Value val1 = new Value();
//修改val0的num值
val0.num = 5;
System.out.println("val0's num = " + val0.num);//val0'num =5
System.out.println("val1's num = " + val1.num);//val0'num =0
- 在堆区开辟内存,存放实例变量,并默认初始化。
- 在栈区声明引用变量val0和val1,让他们分别存储两个堆区对象的地址,意思是让引用变量指向实际对象。
- 两个对象分别独立,互不影响。
类变量
//直接使用类调用类变量
Value.staticNum = 10;
//使用实例对象调用类成员变量,不建议使用
//val0.staticNum = 10;
System.out.println("val0's staticNum =" + val0.staticNum);//10
System.out.println("val1's staticNum =" + val1.staticNum);//10
- 在方法区(不是栈区)存储static修饰的变量,即staticNum。
- 两个引用变量val0和val1还是在栈区存储,且他们指向方法区的同一块内存区域。
- 在同一个类中,实例对象共享类变量。意思是,如果Java程序运行在不同JVM进程中,就不会共享数据。如下:
package com.my.pac04;
/* ClassVal.java */
public class ClassVal {
public static int value = 6;
}
package com.my.pac04;
/* ClassValTest01.java */
public class ClassValTest01 {
public static void main(String[] args) {
ClassVal val01 = new ClassVal();
val01.value = 10;//修改static修饰的值为10
System.out.println(val01.value);
}
}
package com.my.pac04;
/* ClassValTest02.java*/
public class ClassValTest02 {
public static void main(String[] args) {
ClassVal val02 = new ClassVal();
System.out.println(val02.value);//不是10,而是6
}
}
关于JVM及类加载的机制,在之后的学习之中将会继续深入,在这里就不发表自己的肤浅之谈了,之后会进行补充哈。
局部变量
- 定义局部变量时,只有对他进行初始化赋值之后,才会获得系统给予的内存。
- 局部变量不属于类或实例,总是保存在栈内存中,所以随方法或代码块结束而结束,后进先出。
- 基本数据类型存放具体数值,引用类型存放实际引用对象的地址值。
注意:虽然大部分时间,可以之间用成员变量来代替局部变量解决问题,但是这种做法,有几个缺点:
- 增大变量的生存时间,增加内存开销。
- 扩大变量的作用域,不利于提高程序的内聚性。
局部变量的作用范围越小,它在内存中停留的时间就越短,程序性能就会越好。
总结
- 假如定义的变量用于描述某个类或对象的固有信息,请用成员变量。
- 假如定义的变量用于保存类或实例运行的状态信息,请用成员变量。
- 假如定义的变量用于保存共享在多个方法间的消息,请用成员变量。
Java变量在内存中的存储的更多相关文章
- python中变量在内存中的存储与地址关系解析、浅度/深度copy、值传递、引用传递
---恢复内容开始--- 1.变量.地址 变量的实现方式有:引用语义.值语义 python语言中变量的实现方式就是引用语义,在变量里面保存的是值(对象)的引用(值所在处内存空间的地址).采用这种方式, ...
- 详解Python变量在内存中的存储
这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...
- PHP变量在内存中的存储方式
原文:http://www.phppan.com/tag/refcount/ 每门计算机语言都需要一些容器来保存变量数据.在一些语言当中,变量都有特定的类型,如字符串,数组,对象等等.比如C和Pasc ...
- Java常量,变量,对象(字面量)在JVM内存中的存储位置
Java常量,变量,对象(字面量)在JVM内存中的存储位置 2019-02-26 18:13:09 HD243608836 阅读数 540 收藏 更多 分类专栏: JAVA jvm 苦苦研究了快 ...
- String在内存中如何存储(Java)
JDK1.8中JVM把String常量池移入了堆中,同时取消了“永久代”,改用元空间代替(Metaspace)java中对String对象特殊对待,所以在heap区域分成了两块,一块是字符串常量池(S ...
- 【Java】运行时Java对象在内存中是如何存储的?
翻译自这一篇文章 我们知道函数在内存中实现为一个活动记录的栈.我们也知道Java方法在JVM栈区中实现为一个帧栈而Java对象是在堆区进行分配的. Java对象在堆内存中是怎样的呢?一旦对象保存在内存 ...
- 数据在内存中的存储方式( Big Endian和Little Endian的区别 )(x86系列则采用little endian方式存储数据)
https://www.cnblogs.com/renyuan/archive/2013/05/26/3099766.html 1.故事的起源 “endian”这个词出自<格列佛游记>.小 ...
- Java程序在内存中运行详解
目录 Java程序在内存中运行详解 一.JVM的内存分布 二.程序执行的过程 三.只有一个对象时的内存图 四.两个对象使用同一个方法的内存图 五.两个引用指向同一个对象的内存图 六.使用对象类型作为方 ...
- Java变量以及内存分配
Java变量以及内存分配(非常重要) 堆栈 静态存储区域 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操 ...
随机推荐
- cordova 打包出现transformClassesWithDexForDebug一类错误的解决办法
Cordova在添加了插件后,或者是本身文件很多,文件很大的情况下打包时候可能会出现 transformClassesWithDexForDebug或者transformClassesWithDexF ...
- c#截取后台窗口的图片
c#截取后台窗口的图片,自测可用,据说性能很一般,用用吧 struct RECT { public int Left; // x position of upper-left corner publi ...
- 【ES6基础】let、const命令和变量的结构赋值
ES5声明变量(2):var .function ES6声明变量(6):var.function.let.const.import和class 1.let命令和const命令 (1)let和const ...
- Web基础了解版05-Servlet
Servlet Servlet? 从广义上来讲,Servlet规范是Sun公司制定的一套技术标准,包含与Web应用相关的一系列接口,是Web应用实现方式的宏观解决方案.而具体的Servlet容器负责提 ...
- git常用操作合集
基本操作git status 查看文件处于什么状态 git status -s 带上-s参数,可以以更紧凑的格式输出文件状态信息 git add 开始追踪该文件或者暂存已修改的文件. .gitigno ...
- LVM(逻辑卷管理器)部署、扩容、缩小
物理卷 -- Physical Volume -- PV 卷组 -- Volume Group -- VG 逻辑卷 -- Logical Volume -- LV 1.硬盘设备管理技术虽然能够有效 ...
- vue.config.js的常用配置
const path = require('path') const glob = require('glob') const resolve = (dir) => path.join(__di ...
- Android 音视频技术之录音获取实时音量
一.实时音量相关基础知识 说到获取音量,大家首先想到的应该就是分贝(dB),分贝是一个相对单位(是一个比值,是一个数值,是一个纯计数方法). 在音频领域dB度量的是声音的强度,其计算的公式如下: 在上 ...
- CentOS 上配置 lua 的服务器环境(enet)
安装 lua & luarocket 安装依赖 $ yum install gcc gcc-c++ kernel-devel $ yum install readline-dev $ yum ...
- Java之数据库表字段有关键字报错java.sql.SQLSyntaxErrorException
前两天在开发中遇到一个坑,本来我在快乐的做着增删改查,然后悲剧发生了,在查询数据库的过程中,报了java.sql.SQLSyntaxErrorException: 经过排查,是因为数据库表字段中存在关 ...