java基础--05(java常量池)

目录

 

1.java常量池


1.java常量池

    之前汪先生在字符串的博客提到过字符串的常量池,但是今天又遇到一个题,所有有必要把常量池学习一下。

首先为什么要有常量池这个东西?Java采用“动态链接”,与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序;当运行Java程序时,首先运行JVM,然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做“类加载器(class loader)” “通俗的说,Java动态链接”允许一些东西直到运行时才被确定。这是动态常量池,当然还有静态常量池。

常量池中除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值,还包含一些以文本形式出现的符号引用,如:类和接口的全限定名、字段的名称和描述符、方法和名称和描述符,常量池存在于jvm的方法区中。

在编译时,如果发现对其它类方法的调用或者对其它类字段的引用,记录进class文件中的只是一个文本形式的符号引用,在连接过程中,虚拟机根据这个文本信息去查找对应的方法或字段(JVM为Java的“动态”提供了便利)

与Java语言中的所谓“常量”不同,class文件中的“常量”内容很非富,这些常量集中在class中的一个区域存放,一个紧接着一个,这里就称为“常量池”

“常量池”的出现方便了频繁取用某些需要重复引用的东西,在使用前先在常量池中查找,如果再创建一个,也就是说常量池提高了效率。

 Java的包装类,除了浮点数都实现了常量池存储机制(这些类是 Byte , Short , Integer , Long , Character , Boolean):

 注意,Byte , Short , Integer , Long , Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池(这个汪先生也有介绍过Interger.valueOf()的使用),也即对象不负责创建和管理大于127的这些类的对象。
一般情况下,equals和==是一样的都是比较的两者的地址值是不是一样。但是有特殊的情况:我们都知道我们使用的类都是继承自Object基类,Object中equals方法中是使用==来实现的,即比较的是两者的地址值。但是Object的子类可以重写equals方法,比如Date、String、Integer等类都是重写了equals都是重写了,比较的是值是否相等。

常量池就介绍完了,接下来就看看这个题,

        Integer i01 = 59;
        int i02 = 59;
        Integer i03 = Integer.valueOf(59);
        Integer i04 = new Integer(59);
        
        System.out.println(i01==i02);
        System.out.println(i01==i03);
        System.out.println(i03==i04);
        System.out.println(i02==i04);

 分别打印什么?

 这里和字符串常量池还不一样,这个还牵涉到拆箱装箱

 前面两个应该是没有疑问的,首先第一个相比较他们是会发生一个拆箱的过程,然后比较数值,当然是相等的。第二个其实 Integer i01 = 59;就是Integer i03 = Integer.valueOf(59);的简写,并且他们都会拿缓存的值,所以他们也是相等的。

 第三个就有点麻烦了,首先从储存位置上来说,他们肯定是不会相等的,i03指向的是常量池中的一个对象,而i04是实实在在的再堆上创建了一个对象,就看他们最后比较的时候会不会发生一个拆箱的过程?那么到底会不会呢???当然不会,因为两边都是Integer类型,没有int类型,所以不会触发拆箱的过程。

第四个和第三个相比就是出发了拆箱的过程,所以返回true.

经过强制类型转换以后,变量a,b的值分别为多少?

short a =128

byte b =(byte) a;

首先short是两个子节即16位,所表示的数据的范围是[-2的15次方,2的15次方-1].byte一个子节即8位所表示的数据范围是[-128,127],

a的二进制表示形式:00000000  10000000;

强制转换的时候会对a进行强制截断,前面8个0被截断,剩余的这个10000000就是b的补码,首位位1所以为负数,减一计算得到b的反码0111 1111,根据反码得到B的原码1000 0000为128,因为是负数,所以是-128.

补码 :1000 0000
反码: 1000 0000 -1 = 0111 1111
原码: 1000 0000 -128

 

1、Java中用补码形式表示

2、第一位正负位,1表示负,0表示正。

3、原码:一个数的二进制表示。

                 3的原码00000011   -3的 原码 10000011

4、反码:负数原码按位取反(符号位不变)。正数原码本身。

                3的反码00000011   -3的反码11111100

5、补码:正数是原码本身。负数的补码=反码+1。

                 3的补码是00000011  -3的补码是11111101

 

 

 

参考博客:https://blog.csdn.net/abc_12366/article/details/79194313

    

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空恋旅人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值