数据类型& 变量 & JVM存储

数据类型

分为两类:原始数据类型 和 非原始数据类型(引用类型)
在这里插入图片描述
基本类型:
byte short char int long float double boolean

数据类型默认值默认占用内存大小
booleanfalse1 bit
char‘\u0000’2 byte
byte01 byte
short02 byte
int04 byte
long0L8 byte
float0.0f4 byte
double0.0d8 byte

** char 占用2个字节的原因
Java使用Unicode编码(非ASCII码编码),\u0000是Unicode系统的最低范围

溢出:

int a = 130;
byte b = (byte)a;

输出

a = 130
b = -126

int 类型2byte byte类型1byte(-128 ~ 127)
a -> 00000000 10000010
强转为byte,只保留了低八位 10000010

**默认高一位代表符号
原码 – 反码 – 补码
原码 转 反码:除高一位,其他位反转
反码 转 补码 :反码 + 1
则 10000010(原码) – 11111101(反码) – 11111110(-(27 -2)= -126)

变量

是一个值可变的内存位置的名称。
根据变量名可以找到它所引用的数据的内存指针。
根据变量类型可知指针后数据占用的字节数。

变量类型(作用范围的不同) 局部变量 实例变量 静态变量在这里插入图片描述
局部:方法中声明的变量
实例:类中非方法中的非static变量 == 成员变量
静态:类中的static变量
** 局部变量不能被声明为静态的(报错:Modifier ‘static’ not allowed here)

变量类型(数据类型的不同):原始数据类型变量,引用数据类型变量

JVM存储位置

变量在 方法区,栈内存,堆内存 的占用,分为两部分看。
变量 和 变量引用的数据
简称“变量分配” 和 “数据分配”

原始数据类型变量:“变量分配”、“数据分配” 在一起(方法区/堆内存/堆内存)
引用数据类型变量:“变量分配”、“数据分配” 不一定在一起

方法区和堆内存的数据是线程间共享的,线程可访问 方法区的
静态变量以及它所引用的对象的实例变量(static int i; 和 class对象)
** 方法区都是只加载一次的。

栈内存每个线程都有自己的虚拟机栈,栈帧间的数据是线程独有的。

??
在这里插入图片描述

字面量 可以理解为 “值”(等号右边的)

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;
}

在这里插入图片描述
https://www.cnblogs.com/xiaowangbangzhu/p/10366200.html

int a = 1;
String s = “1”,s1 = new String(“1”);
栈:基本数据类型和对象的引用 int a = 1; s,s1;

成员变量,new对象 == 堆
局部变量 == 栈

静态的 == 方法区

常量池:

静态常量池(class文件的常量池) + 运行时常量池

Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。

所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。
而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

虚拟机编译期对常量字符串拼接优化

String s1 = "Hi";
String s2 = "H"+"i"//结果 s1 == s2;
String s3 = "H"+new String("i"); //这种的 编译期不会优化,所以 s1 != s3;(s3在堆中)
String s4 = "H"; String s5 = "i";
String s6 = s4 + s5; // 运行时s4 s5拼接出来的地址在堆中不确定,所以 s1 != s6
//intern方法会尝试将Hi字符串添加到常量池中,并返回地址。
String s8 = new String("Hi");
String s7 = s8.intern();// s1 == s8;

1、必须要关注编译期的行为,才能更好的理解常量池。
2、运行时常量池中的常量,基本来源于各个class文件中的常量池。
3、程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池。

参考:
https://blog.csdn.net/HD243608836/article/details/87940295
https://blog.csdn.net/HD243608836/article/details/87940029
https://www.cnblogs.com/xiaowangbangzhu/p/10366200.html

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值