我们都知道int的范围是-2147483648—2147483647
那么假如一个数被设置成int,加上的值超出2147483647会发生什么呢?
int m=1;
m+=2147483647;
System.out.print(m);
输出是-2147483648
这是因为溢出后java只取低32位所以得到了这个数字(超出的位被舍去了)
同理在java int中乘法溢出中也出现了类似的情况
double d1=1024*1024*1024*1024;
double d2=1024d*1024*1024*1024;
double d3=1024l*1024*1024*1024;
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
输出是0.0
1.099511627776E12
1.099511627776E12
在乘法里Java发现结果已经超出了int基本数据类型的最大范围(2147483647),于是作了默认的类型提升,中间结果做为long类型存放,返回结果时目标数据类型int不能够容纳下结果,于是根据Java的基础类型的变窄转换规则,把结果宽于int类型宽度的部分全部丢弃,也就是只取结果的低32位,于是就得到了上面的结果。
而加上了d或者l的数据则默认以double和long类型存储,故取得了正确的值
再来谈谈使用频率很高的String,我们通常会把它和StringBuffer和StringBuilder联系在一起
String由于使用频繁,为了提高资源效率,有着字符串常量池的机制,一般通过直接量赋值的,放入字符串常量池,通过new方式,则不放入字符串常量池,这两者有什么区别呢?
String i="1234";//直接量 String q=new String("1234");//通过new方式赋值
一般通过直接量赋值的会去字符串常量池中寻找是否建立了,如果已经存在字符串,则直接引用查找到的对象,而通过new方式的则不放入字符串常量池。
String i="1234";
String p="1234";
String q=new String("1234");
System.out.println(i==p);
System.out.println(i==q);
System.out.println(i.equals(q));
结果:true
false
true
在java中两个字符串直接比较的是地址,因为i,p是指向同一个字符串常量池中的对象,所以第一个结果是true,如果要比较两个字符串的值,则应该用equals方法。
关于Stringbuffer和Stringbuilder两者的都实现了Abstract抽象类,拥有几乎一致的调用接口,其底层在内存中的存储方式与String相同,不同点是Stringbuffer和Stingbuilder的值是可以改变的,并且值改变后,引用对象不会发生改变,简单点讲buffer线程是安全的,所以多线程一般选用buffer,builder线程是不安全的,但是比较节省资源,故单一线程建议使用builder。