java 常量pi_JAVA核心技术I---JAVA基础知识(常量设计和常量池)

一:常量---一种不会修改的变量

–Java没有constant关键字

–不能修改,final

–不会修改/只读/只要一份,static–方便访问publicJava中的常量

–public staticfinal

–建议变量名字全大写,以连字符相连,如UPPER_BOU

(一)static和final修饰的常量

public classConstants {//使用static和final做到唯一且不可变//若是不使用static,则每次产生一个对象,就会产生一个变量不可以修改,但是值却相同,无意义且占据大量空间

public final static double PI = 3.14;public static final String DEFAULT_COUNTRY = "China"; //static 和 final两个的顺序可以变化

public static voidmain(String[] args) {

System.out.println(Constants.PI);

System.out.println(Constants.DEFAULT_COUNTRY);

}

}

PI=3.2; //The final field Constants.PI cannot be assigned  出错,编译无法通过

(二)接口内定义的变量默认是常量:不希望别人修改

public interfaceConstantInterface {double PI=3.14;  //默认是public static final double PIpublic doublegetPI();public void setPI(doublepi);

}

public classConstantTest implements ConstantInterface{public doublegetPI() {returnPI;

}public void setPI(doublepi) {this.PI=pi; //The final field ConstantInterface.PI cannot be assigned 出错,编译无法通过

}

}

二:常量池(节约内存,共享访问)

(一)常量池和包装类

Java为很多基本类型的包装类/字符串都建立常量池

常量池:相同的值只存储一份,节省内存,共享访问

包装类:将8个基本类型,都对应产生一个对应的包装类。(因为java基本上操作的都是对象)

(二)8个包装类以及对应的常量池(6个):

基本类型的包装类

–Boolean,Byte,Short,Integer,Long,Character,Float,Double

–Boolean:true, false

–Byte, Character : \u0000--\u007f (0—127)    128个

–Short, Int, Long:-128~127    256个–Float,Double:没有缓存(常量池)

java为前面的六个建立的常量池,因为小数东西太多,没办法用常量池

public static voidmain(String[] args) {

System.out.println(Constants.PI);

System.out.println(Constants.DEFAULT_COUNTRY);//PI=3.2;//The final field Constants.PI cannot be assigned

Integer n1 = 127;

Integer n2= 127;         //在常量池中,所以指向同一块内存

System.out.println(n1==n2);   //true//对象双等号是比较指针是否指向同一个东西

Integer n3= 128;

Integer n4= 128;        //因为包装类Integer只包含-128~127,并没有保存128,所以不在常量池中,不是同一块内存

System.out.println(n3==n4);  //false

Integer n5= new Integer(127);//n1在栈上,n5在堆上,自然不在同一块内存区域,自然不一致

System.out.println(n1==n5);  //false

}

public classCacheTest {public static voidmain(String[] args) {

Boolean b1= true; //true,false

Boolean b2 = true;

System.out.println("Boolean Test:" + String.valueOf(b1 ==b2));

Byte b3= 127; //\u0000-\u007f

Byte b4 = 127;

System.out.println("Byte Test:" + String.valueOf(b3 ==b4));

Character c1= 127; //\u0000-\u007f

Character c2 = 127;

System.out.println("Character Test:" + String.valueOf(c1 ==c2));

Short s1= -128; //-128~127

Short s2 = -128;

System.out.println("Short Test:" + String.valueOf(s1 ==s2));

Integer i1= -128; //-128~127

Integer i2 = -128;

System.out.println("Integer Test:" + String.valueOf(i1 ==i2));

Long l1= -128L; //-128~127

Long l2 = -128L;

System.out.println("Long Test:" + String.valueOf(l1 ==l2));

Float f1= 0.5f;

Float f2= 0.5f;

System.out.println("Float Test:" + String.valueOf(f1 ==f2));  //不在常量池中,不是同一块区域,对象不一致false

Double d1= 0.5;

Double d2= 0.5;

System.out.println("Double Test:" + String.valueOf(d1 ==d2));  //不在常量池中,不是同一块区域,对象不一致false

}

}

(三)字符串常量池

Java为常量字符串都建立常量池缓存

public classStringConstantTest {public static voidmain(String[] args) {

String s1= "abc";

String s2= "abc";

String s3= "ab" + "c"; //都是常量,编译器将优化,下同

String s4 = "a" + "b" + "c";

System.out.println(s1 == s2); //true

System.out.println(s1 == s3); //true

System.out.println(s1 == s4); //true

}

}

对于s1 s2 s3都是由常量拼接,编译器将对其进行优化。存放在同一块常量池中

b8868631cd3e05bf778e19ab904f7c7f.png

(四)包装类的两种创建方式:决定是否被常量化

基本类型的包装类和字符串有两种创建方式

–常量式(字面量)赋值创建,放在栈内存 (将被常量化)

• Integer a= 10;

• String b=“abc”;

–new对象进行创建,放在堆内存 (不会常量化)

• Integer c= new Integer(10);

• String d= newString(“abc”);

这两种创建方式导致创建的对象存放的位置不同

栈读取速度快,但是容量小

堆读取速度慢,但是容量大

(五)包装类和基本类型

1.包装类的名字大写开头,类型名全长

2.数据---->对象 经过自动装箱

int i1 = 10;

Integer i2 = 10; // 自动装箱

1288af351cff3f382b31ed250f80eb1c.png

3.基本类型和包装类型比较时,包装类会自动拆箱。转换为基本数据类型比较

int i1 = 10;

Integer i3 = new Integer(10);

System.out.println(i1 == i3); //true

// 自动拆箱 基本类型和包装类进行比较,包装类自动拆箱

4.两个包装对象比较时,比较其地址

Integer i2 = 10; // 自动装箱

Integer i3 = new Integer(10);

System.out.println(i2 == i3); //false

// 两个对象比较,比较其地址。

// i2是常量,放在栈内存常量池中,i3是new出对象,放在堆内存中

5.两个包装对象运算时,会先拆箱为基本类型进行运算,返回基本类型

int i1 = 10;

Integer i2= 10; //自动装箱

Integer i3 = new Integer(10);

Integer i4= new Integer(5);

Integer i5= new Integer(5);

System.out.println(i1 == (i4+i5)); //true

System.out.println(i2 == (i4+i5)); //true

System.out.println(i3 == (i4+i5)); //true//i4+i5 操作将会使得i4,i5自动拆箱为基本类型并运算得到10.//基础类型10和对象比较, 将会使对象自动拆箱,做基本类型比较

i4+i5返回的是10-->是基本数据类型int,不是Integer包装类

6.装箱的包装对象要参照常量池

int i1 = 10;

Integer i2= 10; //自动装箱

Integer i6= i4 + i5; //+操作使得i4,i5自动拆箱,得到10,再装箱,放入栈中,可以常量化,因此i6 == i2.

System.out.println(i1 == i6); //true

System.out.println(i2 == i6); //true

System.out.println(i3 == i6); //false

i4 + i5 ---> 10 存放在栈区,在常量池中,同i2一样是10,存放在常量池中,所以两者相等

(六)不同类型基本类型和包装类比较

1.基本类型比较

short a=1;int b=1;

System.out.println(a==b);float e = 1;

System.out.println(e);double f=1;

System.out.println(f);

System.out.println(b==e);

System.out.println(b==f);

System.out.println(e==f);

true

1.0

1.0

true

true

true

bbc3de40cd636c7593d9c116db30fafd.png

short a=1;char g=1;byte h=1;

System.out.println(g);

System.out.println(h);

System.out.println(g==h); //一个是char类型,一个是byte类型,两个比较都会转换为int类型

System.out.println(h==a);

1

true

true

1.如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型

2.否则(没有一个是double类型),如果两个操作数中有一个是float类型,另一个操作数就会转换为float类型

3.否则(没有一个是double类型和float类型),如果两个操作数中有一个是long类型,另一个操作数就会转换为long类型

4.否则两个操作数都会被转换为int类型

6372966129a140df39699ad69bcb7999.png

2.不同包装类比较

8ad44ae74bedfa743a9c0379e3e88031.png

不允许不同包装类之间比较,编译无法通过

(七)字符串常量池补充

1.栈和堆

String s0 = "abcdef";  //栈,常量池

String s1= "abc";    //栈,常量池

String s2= "abc";    //栈,常量池

String s3= new String("abc");  //堆,单独开辟一块内存

String s4= new String("abc");  //堆,单独开辟一块内存

System.out.println(s1 == s2); //true 常量池

System.out.println(s1 == s3); //false 一个栈内存,一个堆内存

System.out.println(s3 == s4); //false 两个都是堆内存

dba47715185113655ca9faf5025b5e9d.png

2.字符串拼接涉及变量,则编译器不会优化

String s5 = s1 + "def"; //涉及到变量,故编译器不优化

String s6 = "abc" + "def";//都是常量 编译器会自动优化成abcdef

String s7 = "abc" + new String ("def");//涉及到new对象,编译器不优化

System.out.println(s5 == s6); //false

System.out.println(s5 == s7); //false

System.out.println(s6 == s7); //false

System.out.println(s0 == s6); //true

3.字符串拼接涉及new对象,则编译器不会优化

String s8 = s3 + "def";//涉及到new对象,编译器不优化

String s9 = s4 + "def";//涉及到new对象,编译器不优化

String s10 = s3 + new String("def");//涉及到new对象,编译器不优化

System.out.println(s8 == s9); //false

System.out.println(s8 == s10); //false

System.out.println(s9 == s10); //false

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值