分享

「从面试题看问题」数据类型篇

 xfshok 2017-05-18

「从面试题看问题」数据类型篇

【面试题1】int和Integer有什么区别?

思考1:为什么要有基本类型和包装类型

Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型。但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型。而Integer就是int的包装类型。

下图是JAVA中所以基本类型以及对应包装类型和各自所占用的大小。

「从面试题看问题」数据类型篇

思考2:包装类型和基本类型的区别

1.声明方式不同,基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间;

2.存储方式及位置不同,基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用来使用;

3.初始值不同,基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null

4.使用方式不同,基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用到

思考3:包装类型和基本类型的相互转换?

从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。

自动装箱场景:

List声明的泛型只能为包装类型,将基本类型加入list中发生了自动装箱。

ArrayList<Integer> intList = new ArrayList<Integer>();

intList.add(1);

自动拆箱场景:

用基本类型接收list中的值。

int number = intList.get(0);

延伸题1:

class AutoUnboxingTest {

public static void main(String[] args) {

Integer a = new Integer(3);

Integer b = 3; // 将3自动装箱成Integer类型

int c = 3;

System.out.println(a == b); // false 两个引用没有引用同一对象

System.out.println(a == c); // true a自动拆箱成int类型再和c比较

}

}

延伸题2

public class Test03 {

public static void main(String[] args) {

Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

System.out.println(f1 == f2);

System.out.println(f3 == f4);

}

}

答案是:true,false

这个题有点坑,从源码分析的过程不再说,直接看分析出的结论:

如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1f2的结果是true,而f3f4的结果是false。

【面试题2】:判断以下程序是否有错?错在哪里?

byte b = 'a';

byte c = 1; byte d = 'ab';

byte e = '啊';

byte g = 128;

本题考查的是数据类型能承载数据的大小。看面试题1中的总结我们可以看到各数据类型能承载数据的范围。

1个字节 = 8 bit

一个英文字符 = 1个字节 = 8bit

一个汉字 = 2个字节 = 16bit

byte 最多存放 8bit 所以 b,c是正确的。d,e,g是错误的。

可能你还有疑问:为什么数据区间在 -128到127呢?

下面补充一下位运算的知识.

计算机中都是以2进制存储数据的,1个bit代表着可以存放一个二进制符号。所以8个位置的二进制符号可以有2的8次方即256种组合方式。-128到127加上0正好是256个数。这样理解可能有些牵强,我们举例子来看:

计算机中使用补码来表示数据。

原码:第一位是符号0位正,1为负,剩余为2进制数。

反码:符号不变,其他取反。

补码:反码加1。

正数的补码等于原码。

负数的补码等于原码取反后加1。

「从面试题看问题」数据类型篇

「从面试题看问题」数据类型篇

延伸题1

下面的语句哪些有问题?

byte b1 = 3;

byte b2 = 4;

byte b3 = b1 + b2;

byte b3 = b1 + 1;

byte b4 = 3+7;

short c1 = 3;

short c2 = 3;

short c3 = c1 +c2;

short s = 1;

s = s + 1;

s += 1;

int a1 = 3;

int a2 = 4;

int a3 = a1+a2;

记住以下要点:

(1)公式中,两个byte 或者两个 short相加,默认类型提升为int ,如果再赋值给byte或short,会损失经度,报错,需要强转。

(2)公式中,有小类型和大类型,首先小类型转为大类型如 byte 和 int 相加 默认返回int 可以强制转换。

所以 如下语句是有问题的:

byte b3 = b1 + b2;

byte b3 = b1 + 1;

short c3 = c1 +c2;

两个常量相加,没有问题,比如:

byte b4 = 3+7;

使用+=运算符没有问题,因为+=中隐含了强制转换。

s+=1;

延伸题2

float f=3.4;是否正确?

3.4是双精度数,将双精度型(double)赋值给浮点型(float)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F;。

【面试题3】String和StringBuilder、StringBuffer的区别?

StringBuffer、StringBuilder和String一样,也用来代表字符串。

  • String类是不可变类,任何对String的改变都 会引发新的String对象的生成;

  • StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象。

  • StringBuilder和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer要高。

千万不要被思维定式误导,你可能以为拼接少量字符串的时候

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多