面试java被叫去做前端_Java面试陷阱,你不能不知道

java作为一门面向对象的编程语言,在里面运用了类的概念,程序的处理又有编译阶段和运行阶段之分,这导致很多刚开始学习java的人都不够理解,从而犯下很多错误。但今天说的这些,不只是初学者,很多有一点工作经验但不丰富的,也未必知道,平时几乎用不上,但在面试时,却最容易被用来做考题。下面就是两个典型的例子。

先看下面的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

publicstaticvoidmain(String[]args){

Stringa1="123456789";

Stringa2="12345";

Stringa3="6789";

Stringa4=a2+a3;

Stringa5="12345"+a3;

Stringa6="123456789";

Stringa7="12345"+a3;

Stringa8=a2+a3;

System.out.println(a1==a4);//true or false?

System.out.println(a1==a5);//true or false?

System.out.println(a1==a6);//true or false?

System.out.println(a4==a5);//true or false?

System.out.println(a7==a5);//true or false?

System.out.println(a8==a4);//true or false?

}

在看文章时,请先不要看答案,你能很确定的说出上面的所有结果吗?

正确的答案是:

false

false

true

false

false

false

对于没答对,或者靠蒙对的人,也许你会在想,这是为什么呢?

答案就在于,Java为了节约内存,防止多余的内存开销,所以内存中已经存在的,它不会再重新创建,而是直接引用。比如:String a1 = “123456789”,会生成一个String类型的变量a1,再去看内存中存不存在”123456789″这个字符串常量,如果有,则直接引用,没有,则创建,可惜的是,并没有找到,所以会创建一个字符串常量 “123456789”,同时让a1指向这个字符串常量。a2,a3也是如此,但对于a4和a5,就不一样了。因为a2,a3已经存在,再对于已有的部分,他们只会引用,而不会重新再创建。只有没有的部分才创建。所以对于a5,它会自己创建一个”12345″,再引用一个a3,而a4,直接引用a2和a3。故a1不等于a4和a5,a4也不等于a5。对于a6,因为”123456789″已经存在,则会直接对它进行引用,所以a1和a6指向的是同一个字符串常量,它们相等。

但如果换成下面这样,结果又如何呢?

1

2

3

4

5

6

System.out.println(a1.equals(a4));//true or false?

System.out.println(a1.equals(a5));//true or false?

System.out.println(a1.equals(a6));//true or false?

System.out.println(a4.equals(a5));//true or false?

System.out.println(a7.equals(a5));//true or false?

System.out.println(a8.equals(a4));//true or false?

答案是结果全部为true。因为字符串的equals()方法在比较的时候,比较的是字面值。而上面比较的所有变量,字面值都为123456789,结果自然都为true了。

可如果换成下面这样,结果你又能否都明确的说出来呢?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Stringa1="123456789";

finalStringa2="12345";

finalStringa3="6789";

finalStringa4=a2+a3;

finalStringa5="12345"+a3;

Stringa6="123456789";

finalStringa7="12345"+a3;

finalStringa8=a2+a3;

System.out.println(a1==a4);//true or false?

System.out.println(a1==a5);//true or false?

System.out.println(a1==a6);//true or false?

System.out.println(a4==a5);//true or false?

System.out.println(a7==a5);//true or false?

System.out.println(a8==a4);//true or false?

答案也是全部为true。这里面就是final变量和普通变量的区别了,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问这个确切的常量,不需要在运行时确定。因此在上面的一段代码中,由于变量a2,a3,a4,a5,a7,a8被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将它们 替换为它们的值。所以结果为true。

不过要注意,只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,对于不知道的,就不会了。比如下面的这段代码就不会进行优化:

1

2

3

4

5

6

7

8

9

10

11

12

13

publicclassTest{

publicstaticvoidmain(String[]args){

Stringa="hello2";

finalStringb=getHello();

Stringc=b+2;

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

}

publicstaticStringgetHello(){

return"hello";

}

}

好了,说完了上面的,我们再来看下面的这个例子。

1

2

3

4

5

publicstaticvoidmain(String[]args){

Integera=10;

Integerb=10;

System.out.println(a==b);//true or false?

}

你知道答案是什么吗,我相信大家都会很明确的回答true。嗯,不错,就是true。接着再来看下面:

1

2

3

4

5

publicstaticvoidmain(String[]args){

Integera=128;

Integerb=128;

System.out.println(a==b);//true or false?

}

也许你会好不犹豫的回答,这不跟上面一样吗,同样是true啊。可也有的人会想,既然我文章标题都说了java的陷阱,怕是没那么简单吧。不管怎样,答案就是false,你是不是很吃惊啊,怎么会这样!

答案在于,对于java里面的封装数据类型,它的范围是有限制的,对于Integer,它的范围就是-128-127,任何大于127或小于-128的两个Integer相比较,都为false。这下你明白了吧。对于其它的几个,我也没一一测试,就留给读者了,毕竟写代码这东西,要多动手,如果看到这里,你也不亲自动手试试的话,未免太懒了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值