java变量与内存深入了解
=========================================================================================
在我看来,学习java最重要是要理解what(这东西是什么),why(为什么要用它),where(在哪用它),how(怎么用)。所以接下来,我都是以这样的思想来和大家交流,从最基础的知识讲起。如果有啥出错的,欢迎大家前来批评。本人虚心接纳。
=========================================================================================
一.前言
对于变量,我们再熟悉不过了,谁都知道声明一个变量,赋值。其实一直以来,变量也并不简单,我们很少系统地整理分类,更少研究变量对应的储存结构,这次就深入地了解一下变量,以及常量。
二.What(什么是变量,先从变量说起)
1.变量的简单定义:通俗来说,变量就是可以被改变的数据。在程序中声明变量的语法格式如下: 数据类型 变量名称= 值 例如:int x= 1,数据类型定义这个变量是什么类型的(有整型,浮点型等),变量名称只是个别名,值就是对应的数据。
2.变量的深入定义:由上面可知,变量就是一个可改变的数据,既然是数据,在计算机中肯定有对应的存储空间来存储这个数据。也就是说,变量其实就是内存中的一个存储空间,用来存储数据。那这么说,声明一个变量,也就是相当于变量空间的开辟,那么,变量的深入定义还对应上面简单定义哪些呢?
(1).声明一个变量=变量空间的开辟
(2).变量的数据类型=这个空间要存储什么数据?
(3).变量名称=这个空间叫什么名字?
(4).变量的值=这个空间的第一次数据是什么?
那么, 这些变量空间究竟在哪里呢?其实这些变量空间对应计算机内存的堆栈,下面会详细讲解。
3.变量的分类
(1).按声明的位置来分类:
a.成员变量:声明在方法之外的变量,不过没有 static 修饰。可以不设值,因为有默认值(下面数据类型会有默认值)。
b.局部变量:声明在类的方法中的变量。必须对其初始化,否则编译不过。
c.类变量:声明在方法之外的变量,用 static 修饰。
(2).按数据类型划分(也就是定义数据是什么类型)
a.基本数据类型:
byte:在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0
short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值0
int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0
long:长整型,在内存中占64位,即8个字节-2^63~2^63-1,默认值0L
float:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0
double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0
char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空
boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false
注意:整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换从低级到高级:byte,short,char—> int —> long—> float —> double
(1).强制类型转换: 转换过程中可能导致溢出或损失精度


(2).自动类型转换:必须满足转换前的数据类型的位数要低于转换后的数据类型,例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float 数据类型的位数为32,可以自动转换为64位的double类型。
b.引用数据类型: 除了8中基本类型以外剩下的都是引用类型(类,接口,数组等,后面详细介绍,new的是引用类型)
String:一定要注意,string是引用类型,不是基本类型。
那么,就有人问了,基本类型和引用类型有啥区别,啥是引用类型,这就有很大学问了,顺便也扯上了变量内存结构了。
(3).详细讲解基本类型和引用类型的区别以及两者在内存的存储位置
a.上面说过了变量声明就是一个内存空间的开辟,那这些内存空间在哪呢?
首先了解一下java内存结构:JVM分了5片内存:
1.程序计数器:记录程序执行到哪一个指令
2.本地方法栈:与虚拟机栈功能相似,不过虚拟机栈为java方法服务,本地方法栈为Native方法服务
3.方法区:存放字节码,常量 ,静态变量,是一个共享的区域
4.虚拟机栈:执行方法其实就是栈帧入栈,出栈的过程,因为是跟方法有关的,而且局部变量常常在方法中,所以栈存储的是局部变量

5.堆:存放引用类型,成员变量
注意:(1).我们接触最多的是堆和栈(虚拟机栈),这里一定要注意这两个的区别。
(2).栈主要是存储方法帧的,每执行一个方法的时候,就会为该方法创建一个栈帧,使其入栈。然而局部变量一般随着方法生成而存在,所以局部变量存储在栈中。
(3).堆一般用来存放引用型对象,以及对应的成员变量,当对象创建时,会在堆中开辟一块地址,并给这个对象的成员变量使用。
b.基本类型没什么好说的,就是一个空间存储数.但注意:很多网上教程会说,基本类型是存在栈中,这是错误的,因为基本类型也分成员变量和局部变量,局部变量随着方法入栈就存在栈中,而成员变量会随着对象在堆中空间的开辟而存储在堆中。例如: int[] a=new int[]{1,2}; 由于new了一个对象,所以new int[]{1,2}这个对象时存储在堆中的,也就是说1,2这两个基本数据类型是存储在堆中。
c.引用类型就比较特别,引用类型占用两块内存,一个栈,一个堆, 栈中存放的是堆中的地址。啥意思?什么是引用类型?举个简单例子,一间房子,我可以在里面 放置家具,放完后用钥匙锁着,把钥匙放在抽屉里面,那我想找某个家具是不是通过钥匙来找到房间再进去找家具。从这个例子我们可以对应一下,房间就是内存堆开辟的空间,家具就是数 据,钥匙就相当于引用类型(堆中的地址),抽屉相当于栈,具体的数据放在堆上,引用类型放在栈上。例如:String s=new String("hello world"),new出来的hello world是存放在堆中,并且将这个堆地址给栈中s来保存。

(4).变量的作用域:
a.从定义上说,变量作用域到大括号结束,出了大括号就就不存在了
b.从内存上解释,一个类中什么时候有大括号的存在?只有两种情况,一个是类两端有大括号,例如:public class Person{},还有是类里面的方法有大括号,例如:public void a(){}。先说类里面的方法,上面也说了,执行完这个函数就相当于出栈,那么局部变量也当然随着函数的结束而销毁,大括号等同于这个类或方法已经执行完了,也就是说作用域只在大括号内,出了大括号就意味着函数结束了,也就是出栈了,变量作用域就无效了。同理,类两端里面是全局变量,执行到大括号也就是类被释放了,对应的全局变量也没了。
(5).举个例子说明一下


上面方法执行流程为:
1.main方法的栈帧入栈,在main的帧当中有一个a= 20;
2.当执行show(a)时,此时传入了一个参数a= 20;执行show方法,show方法的栈帧入栈,第一次打印结果为a= 20,a改为50,再次打印 结果为:a = 50;
3.当执行完show方法后,show方法的栈帧就会出栈;
4.此时栈中只有一个main方法的栈帧,所以在执行完show方法后,再去打印a ,此时a = 20;
三.总结
1.这篇文章更多是强调变量对应的内存关系,详细了解堆栈,一定要明确好关系。
2.引用型基本上都是new出来的,string特别点,引用型new出来的内容放在堆上,地址存放在栈上。
3.基本类型也分成员变量和局部变量,局部变量随着方法入栈就存在栈中,而成员变量会随着对象在堆中空间的开辟而存储在堆中。
4.局部变量是存储在栈中,成员变量是存放在堆中(因为随着类的创建生成,类创建是在堆上)。
===========================================================================
用心查阅,有心分享,分享之际,互相指教,受益你我,何乐不为?
===========================================================================
java变量与内存深入了解的更多相关文章
- Java变量在内存中的存储
目录 Java变量在内存中的存储 成员变量 局部变量 总结 Java变量在内存中的存储 以下探究成员变量和局部变量在内存中的存储情况. package com.my.pac04; /** * @aut ...
- Java变量以及内存分配
Java变量以及内存分配(非常重要) 堆栈 静态存储区域 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操 ...
- Java线程工作内存与主内存变量交换过程及volatile关键字理解
Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模 ...
- Java中堆内存和栈内存详解2
Java中堆内存和栈内存详解 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...
- 如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码
程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习< ...
- java运行时内存模式学习
学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...
- Java中堆内存和栈内存详解
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- 1 Java线程的内存可见性
Java内存的可见性 可见性: 一个线程对共享变量的修改,能够及时被其它线程看到 共享变量: 如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量 Java内存模型(JM ...
- java中string内存的相关知识点
(一):区别java内存中堆和栈: 1.栈:数据可以共享,存放基本数据类型和对象的引用,其中对象存放在堆中,对象的引用存放在栈中: 当在一段代码块定义一个变量时,就在栈中 为这个变量分配内存空间,当该 ...
随机推荐
- ubuntu mount u盘以及cp拷贝文件夹
如果是ubuntu桌面环境的话,不用mount,接入的U盘就可以直接被系统识别,访问起来非常方便,但如果没有桌面环境呢,比如在ubuntu server端,如何访问U盘呢? 第一步:查看U盘信息sud ...
- 程序员 各种PDF格式电子书--免费网盘资源
Java <设计模式之禅(完整高清版)> 链接:http://pan.baidu.com/s/1bo7noMb 密码:5kve <重构_改善既有代码的设计> 链接:http: ...
- ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQL&EF
本章将介绍如何通过Entity Framework来使用My SQL,之前介绍EF时介绍了provider这个配置项,而且也介绍了在ASP.NET访问MySQL数据仍然是通过ADO.NET,不同的地方 ...
- Java API 常用类(一)
Java API 常用类 super类详解 "super"关键字代表父类对象.通过使用super关键字,可以访问父类的属性或方法,也可以在子类构造方法中调用父类的构造方法,以便初始 ...
- web容器启动后自动执行程序的几种方式比较
1. 背景 1.1. 背景介绍 在web项目中我们有时会遇到这种需求,在web项目启动后需要开启线程去完成一些重要的工作,例如:往数据库中初始化一些数据,开启线程,初始化消息队 ...
- Linux-Nand Flash驱动(分析MTD层并制作NAND驱动)
1.本节使用的nand flash型号为K9F2G08U0M,它的命令如下: 1.1我们以上图的read id(读ID)为例,它的时序图如下: 首先需要使能CE片选 1)使能CLE 2)发送0X90命 ...
- OpenWRT (RT5350) 使能两个串口
OpenWRT(RT5350) 默认使能一个串口(uartlite) ,当做console口了,另外一个串口(uartf)与gpio复用. 在查找资料的过程中,发现在新的内核中使用到了设备树(devi ...
- linux下开机不自动挂载指定分区
我的debian装好后,有保留windows,但是却不想在debian启动后桌面上,文件管理器中显示windows分区,留个记录在这里,需要的时候方便查看 使用mount 的 noauto参数: 创建 ...
- CSS组件
下拉菜单 .dropdown:将下拉菜单触发器和下拉菜单包含在其中 .dropdown-menu:给<ul>制定下拉菜单的样式 .dropup:向上弹出菜单 .dropdown-menu- ...
- vue.js快速搭建图书管理平台
前 言 上一期简单讲解了vue的基本语法,这一次我们做一个小项目,搭建一个简单的图书管理平台,能够让我们更深刻的理解这门语言的妙用. 1.DEMO样式 首先我们需要搭建一个简单的demo样式 ...