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变量在内存中的存储的更多相关文章

  1. python中变量在内存中的存储与地址关系解析、浅度/深度copy、值传递、引用传递

    ---恢复内容开始--- 1.变量.地址 变量的实现方式有:引用语义.值语义 python语言中变量的实现方式就是引用语义,在变量里面保存的是值(对象)的引用(值所在处内存空间的地址).采用这种方式, ...

  2. 详解Python变量在内存中的存储

    这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...

  3. PHP变量在内存中的存储方式

    原文:http://www.phppan.com/tag/refcount/ 每门计算机语言都需要一些容器来保存变量数据.在一些语言当中,变量都有特定的类型,如字符串,数组,对象等等.比如C和Pasc ...

  4. Java常量,变量,对象(字面量)在JVM内存中的存储位置

    Java常量,变量,对象(字面量)在JVM内存中的存储位置 2019-02-26 18:13:09 HD243608836 阅读数 540  收藏 更多 分类专栏: JAVA jvm   苦苦研究了快 ...

  5. String在内存中如何存储(Java)

    JDK1.8中JVM把String常量池移入了堆中,同时取消了“永久代”,改用元空间代替(Metaspace)java中对String对象特殊对待,所以在heap区域分成了两块,一块是字符串常量池(S ...

  6. 【Java】运行时Java对象在内存中是如何存储的?

    翻译自这一篇文章 我们知道函数在内存中实现为一个活动记录的栈.我们也知道Java方法在JVM栈区中实现为一个帧栈而Java对象是在堆区进行分配的. Java对象在堆内存中是怎样的呢?一旦对象保存在内存 ...

  7. 数据在内存中的存储方式( Big Endian和Little Endian的区别 )(x86系列则采用little endian方式存储数据)

    https://www.cnblogs.com/renyuan/archive/2013/05/26/3099766.html 1.故事的起源 “endian”这个词出自<格列佛游记>.小 ...

  8. Java程序在内存中运行详解

    目录 Java程序在内存中运行详解 一.JVM的内存分布 二.程序执行的过程 三.只有一个对象时的内存图 四.两个对象使用同一个方法的内存图 五.两个引用指向同一个对象的内存图 六.使用对象类型作为方 ...

  9. Java变量以及内存分配

    Java变量以及内存分配(非常重要) 堆栈 静态存储区域 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操 ...

随机推荐

  1. 测试开源.net 混淆器ConfuserEx

    由于公司业务需要简单的把代码加密混淆,于是了解了一下相关的工具然后打算用ConfuserEx试试. 开源地址:https://github.com/yck1509/ConfuserEx/ 下载地址:h ...

  2. 小白的springboot之路(十四)、AOP

    0.前言 1.什么是AOP AOP(面向切面编程),是一种横切技术,是对OOP的补充和完善: 使用AOP的横切,可以对系统进行无侵入性的日志监听.事务.权限管理等: 思想上跟拦截器其实类似;拦截器是对 ...

  3. IUSEP研修报告

    目录 Introduction Alberta - Edmonton University of Alberta IUSEP Schoolwork and Project Principle of F ...

  4. python基础实战之猜年龄游戏

    目录 一.Python基础实战之猜年龄游戏 给定年龄,用户可以猜三次年龄 年龄猜对,让用户选择两次奖励 用户选择两次奖励后可以退出 age = 18 # 答案 count = 0 # 游戏次数控制 p ...

  5. ubuntu14.04编译vim8.1

    安装依赖 这一步其实我没做,直接下载编译成功了.估计有些包不是必需的.姑且列在这里供参考 sudo apt install libncurses5-dev libgnome2-dev libgnome ...

  6. 微信小程序目录结构与配置介绍

    一.小程序结构目录 小程序框架提供了自己的视图层描述语言 WXML 和 WXSS,以及 JavaScript,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑. 官网 1.1 ...

  7. Oracle Proc编程性能优化经验

    Proc 是Oracle提供的一种数据库操作的API.它是基于ESql技术的,需要预编译后才可以变成普通c代码,非常不直观,使用起来不太方便,阅读也存在困难. 因为这些问题导致程序员平时开发中会出现一 ...

  8. HTML DOM 学习

    HTML DOM 学习 By: Mirror王宇阳 E-mail:2821319009@qq.com 博客主页:https://www.cnblogs.com/wangyuyang1016/ DOM ...

  9. Mac 安装nginx之后重启、停止、开启等操作

    操作系统:macOs High Sierra 10.13.6 1.我用的homebrew安装的nignx1.15.9,安装完成之后会有下面的提示: 网站根目录在:/usr/local/var/www ...

  10. gdisk转fdisk

    分区测试的时候发现之前用gdisk分区之后,就无法用fdisk进行分区了,哪怕格式化了也不行,通过fdisk 查看硬盘,发现硬盘都变成了GPT分区,无法通过fdisk进行分区操作,所以要通过parte ...