目录
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