Java中的变量根据不同的标准可以分为两类,以其引用的数据类型的不同来划分可分为“原始数据类型变量和引用数据类型变量”,以其作用范围的不同来区分可分为“局部变量,实例变量和静态变量”。

根据“Java中的变量与数据类型”中的介绍,“变量是在内存中分配的保留区域的名称。换句话说,它是一个内存位置的名称”,也就是说我们通过这个变量名字就可以找到一个指向这个变量所引用的数据的内存指针,根据变量的类型我们可以知道这个指针之后的几个字节里存储了这个变量所引用的数据。

所以,了解变量在方法区、栈内存、堆内存中的分配要了解两部分内容,一个是“变量在内存中的分配”,另一个是“变量所引用的数据在内存中的分配”。以下简称为“变量分配”与“数据分配”。

原始数据类型变量:
原始数据类型变量的“变量分配”与“数据分配”是在一起的(都在方法区或栈内存或堆内存)

引用数据类型变量:
引用数据类型变量的“变量分配”与“数据分配”不一定是在一起的。

示例代码:

 class Fruit {
static int x = 10;
static BigWaterMelon bigWaterMelon_1 = new BigWaterMelon(x); int y = 20;
BigWaterMelon bigWaterMelon_2 = new BigWaterMelon(y); public static void main(String[] args) {
final Fruit fruit = new Fruit(); int z = 30;
BigWaterMelon bigWaterMelon_3 = new BigWaterMelon(z); new Thread() {
@Override
public void run() {
int k = 100;
setWeight(k);
} void setWeight(int waterMelonWeight) {
fruit.bigWaterMelon_2.weight = waterMelonWeight;
}
}.start();
}
} class BigWaterMelon {
public BigWaterMelon(int weight) {
this.weight = weight;
} public int weight;
}

内存分配图:

同一种颜色代表变量和对象的引用关系:

由于方法区和堆内存的数据都是线程间共享的,所以线程Main Thread,New Thread和Another Thread都可以访问方法区中的静态变量以及访问这个变量所引用的对象的实例变量。ps:方法区存储的都是只加载一次的。

栈内存中每个线程都有自己的虚拟机栈,每一个栈帧之间的数据就是线程独有的了,也就是说线程New Thread中setWeight方法是不能访问线程Main Thread中的局部变量bigWaterMelon_3,但是我们发现setWeight却访问了同为Main Thread局部变量的“fruit”,这是为什么呢?因为“fruit”被声明为final了。

当“fruit”被声明为final后,“fruit”会作为New Thread的构造函数的一个参数传入New Thread,也就是堆内存中Fruit$1对象中的实例变量val$fruit会引用“fruit”引用的对象,从而New Thread可以访问到Main Thread的局部变量“fruit”。

最新文章

  1. chrome拓展开发实战:页面脚本的拦截注入
  2. oracle数据库连接慢的问题
  3. MKRCVCD-MKRCVCDSER.exe can't start in service
  4. linux crontab定时任务调用CI框架PHP代码
  5. 关于IDW空间插值
  6. std::bind(二)
  7. 《OpenGL着色语言》理解点记录二
  8. Smart20学习记录----异步通知
  9. as 和is的区别
  10. Spark SQL概念学习系列之Spark SQL的简介(一)
  11. Html和JS基础
  12. php 判断是不是https链接
  13. python处理时间--- datetime模块
  14. codeforces-1142 (div1)
  15. NYOJ127 星际之门(一)【定理】
  16. 理解django框架中的MTV与MVC模式
  17. des结合base64加解密的python源码
  18. SQLServer将服务器A表写到服务器B表
  19. javaBean的理解总结
  20. Centos7 安装JDK环境和Tomcat

热门文章

  1. java信号量
  2. sql的插入或者修改
  3. 新添加的用户无法sudo解决方案
  4. 配置 Jenkins 连接 Kubernetes 集群
  5. 在电脑上远程连接你的 云服务器( ECS)
  6. 解决centos chrome浏览器页面中文显示为方框
  7. SpringCloud 基础
  8. Linux平台上常用到的c语言开发程序
  9. mybatis-plus-generator 模板生成代码
  10. 比较器Comparable和Comparator