点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

来源:https://www.sohu.com/a/357927861_115128

作为一门面向对象的编程语言,Java 凭借其简单易用、功能强大的特点受到了广大编程爱好者的青睐,伴随着开源社区的推波助澜,Java 语言更是席卷全球,势不可挡,在世界各地都有 Java 技术的从业者,它也常年高居编程语言排行榜的首位,足以表明 Java 的强悍与王者之风。

然而,即便是如此强大的编程语言,也有很多“坑爹”的功能,稍不注意,我们就会掉入坑里,轻则遭到同事的嘲笑和鄙视,重则造成悲惨后果而不得不跑路。

当然,坑爹这个词加上了双引号,因为大部分时候,都是由于我们不够熟练、违反我们的常识才造成了令人不愉快的后果

今天我们就来梳理一下 Java 中最“坑爹”、最违反常识的功能点,以排行榜的方式发布,以飨读者。说明一下,本文中的代码基于 JDK8 来编译实现。

10、switch 必须加上 break 才结束

对于多重分支选择,一系列的 if-else-if 语句会让代码的可读性变差,建议使用 switch 语句来代替,然而 switch case 中的分支判断,必须加上 break 语句才会中止其它 case 的执行,比如:

int count = 1;
switch(count){case 1:System.out.println("one");case 2:System.out.println("two");case 3:System.out.println("three");
}

上面的代码会输出:

one
two
three

然而,这并不是我们想要的,或者说违反了我们的常识。满足了某种条件,当然就只需要执行这种条件下的逻辑即可,其他的 case 应该不予理会、直接跳过,象上面这段代码,只需要输出 one 就行了。当然,在每个 case 结尾处加上 break 就可以达到我们期望的效果。

这个功能点稍显“坑爹”,也是初学者常犯的错误,所以它也光荣上榜,排名第 10 位。

9、逻辑运算符的“短路”现象

使用逻辑运算符时,我们会遇到“短路”的现象:一旦能够确定整个表达式的值,就不会计算余下的部分了,当然,这个功能点其实是非常有用的,但对于初学者来说,可能会感觉比较惊讶,使用不当就会产生“坑爹”后果。比如下面的代码:

int num = 1;
System.out.println(false && ((num++)==1));
System.out.println(num);

就会输出false和1,因为逻辑与&&的前半部分为false,不管后半部分为true还是false,整个表达式都会返回false,所以就不会再计算后面的部分了,如果把false改成true,那么后半部分就会得到执行,num也就变成2了。

它在“坑爹”榜单中位列第9位。

8、数组下标从零开始

Java程序员都清楚,数组的下标是从零开始的,比如,我们要遍历一个数组,可以采用如下的方式:

int[] arr = new int[]{1,3,5,7,9};
for(int i=0;i<arr.length;i++){
System.out.println("the element is:"+arr[i]);
}

这跟我们日常生活中的经验是相违背的,正常情况都是从第1个元素开始计数的,特别是对于初学者来说有点难以接受,会觉得很惊讶。即使对于经验丰富的程序员来说,有些地方也需要格外注意,比如:

String str = "hello world";
System.out.println(str.charAt(1));

我们知道,charAt的作用是获取字符串中某个位置的字符,然而,上面的代码并不是输出第一个字符h,而是e,因为数组是从零开始计数的,这个也是比较“坑爹”啊。当然,设计者这么做的原因是考虑到了内存偏移量的因素。

每次在编写这样的代码时,都需要做这样的1到0的映射和转换(熟练了就是下意识的转换),确实也有点“坑爹”,所以它也不能幸免,排在第8位。

7、ArrayList遍历删除时报错

Talk is cheap,先上代码:

public static void main(String[] args) {  List<String> list = new ArrayList<String>();  list.add("abc");  list.add("bc");  list.add("bc");  list.add("abcd");  list.add("abcdef");  //报错  int length = list.size();  for(int i = 0;i < length;i++){  if(list.get(i).equals("bc")){  list.remove(i);  }  }
}

想从ArrayList中删除某个元素,于是,我们就写了上面的代码,但是它却抛出了IndexOutOfBoundsException异常,原因是ArrayList在删除元素后会重新计算数量,把list.size放在for循环中即可:

for(int i=0;i<list.size();i++){  if(list.get(i).equals("bc")){  list.remove(i);  }
}

当然,这种方法也存在问题,建议使用迭代器的方式来删除元素。

对于不太熟练的程序员来说,有时候就会掉入这样的陷阱之中。这是排名第7的情况。

6、字符转成数字的坑

有时候,我们想把字符直接通过类型转换变成整数,比如像下面这样:

char symbol = '8';
System.out.println((int) symbol);

我们想要的结果是8,然而,上面的代码却输出了56,略显“坑爹”,具体原因参考ASCII的知识。

5、while循环体的“障眼法”

对于while循环语句,如果你没有加上大括号,即使后面的语句挨在一起,也只会执行第一条statement,比如:

int i = 0;
while(i++<3)  System.out.print("A");  System.out.print("B");

上面的代码会输出:

AAAB

而不是3个A、3个B,更“坑爹”的是,如果两条语句放在一行上,迷惑性会更大:

int i = 0;
while(i++<3)  System.out.print("A");System.out.print("B");

上面这种写法同样是输出AAAB。所以,象这样的情况,哪怕只有一条语句,也建议加上大括号,完美避坑。

4、Integer类有缓存

这个功能点也是面试的高频热点之一,稍不注意,也有可能被带入沟里,我们看看下面这段代码:

public static void main(String[] args){  Integer a = 100;  Integer b = 100;  Integer c = 200;  Integer d = 200;  System.out.println(a==b);  System.out.println(c==d);
}

上面的代码竟然输出:

true
false

这确实太出乎意料了,同样的代码,只是数值不同(而且差别不太大的样子),就产生了不一样的输出,这也太离谱了。

原来,Integer中有一个静态内部类IntegerCache,在类加载的时候,它会把[-128, 127]之间的值缓存起来,而Integer a = 100这样的赋值方式,会首先调用Integer类中的静态valueOf方法,这个方法会尝试从缓存里取值,如果在这个范围之内就不用重新new一个对象了:

public static Integer valueOf(int i) {  if (i >= IntegerCache.low && i <= IntegerCache.high)  return IntegerCache.cache[i + (-IntegerCache.low)];  return new Integer(i);
}

此功能入选“坑爹”排行榜的第4名。

3、空方法体导致死循环

如果循环的方法体为空,则会导致死循环,比如,下面的代码打印出数字1,2,3:

int i = 1;
while(i<4){  System.out.println(i++);
}

如果你在敲键盘的时候,不小心在while结尾处加了一个分号(如果方法体没有加大括号,更容易产生这种情况):

int i = 1;
while(i<4);{  System.out.println(i++);
}

你猜怎么着,上面的代码可以正常编译并运行,然而,它却陷入了死循环……是不是非常“坑爹”?for循环也存在类似的情况。

它高居排行榜的第3位。

2、神奇的=+

我们知道,对于类似a=a+b这样的赋值语句,有一种简写方式:a +=b,然而,如果你不小心写成了a =+ b,结果又会是什么呢?我们看看下面的代码:

int i = 100;
i =+ 2;  //注意,加号在后面
System.out.println(i);

上面的代码既不会输出102,也不会报错,而是输出2,这的确出乎意料,完全不是我们期望的结果,太神奇了,非常的“坑爹”。

所以,它排名第2,稳居榜眼的位置。

1、Java注释能够识别Unicode

先看看代码:

public static void main(String[] args){  // \\u000d System.out.println("Hello World!");
}

乍一看,代码都被注释掉了,当然不会输出任何东西,然而,它还是输出每个程序员都倍感亲切的Hello World,这是因为,unicode解码发生在代码编译之前,编译器将\u样式的代码进行文本转义,即使是注释也是这样,然后\u000a被转换成\n换行符,所以println代码得以正常执行。

这样的功能着实“坑爹”,极其违反常识,它必须要上榜,必须要荣登状元的位置。

以上就是Java语言中十大“坑爹”的功能点,你是否认同这样的排名?你觉得有哪些功能更应该入选此榜单?欢迎后台留言讨论!

往期推荐

基于 Spring Cloud 开发的分布式系统,遇到爬虫、接口盗刷怎么办?

Java反射是什么?看这篇绝对会了!

如何评估一项技术是否值得长期投入

四种常见的系统架构,目前你处于哪个阶段呢?

Redis 创始人宣布退居二线:我写代码只是为了表达自己!

扫一扫,关注我

一起学习,一起进步

Java 语言中十大“坑爹”功能!相关推荐

  1. Java 中 10 大坑爹功能!

    今天我们就来聊一下 Java 中的 10 大坑爹功能,它们分别是: 1.switch必须加上break才结束 2.逻辑运算符的"短路"现象 3.数组下标从零开始 4.ArrayLi ...

  2. 后端:Java 中 10 大坑爹功能!

    1.switch必须加上break才结束 2.逻辑运算符的"短路"现象 3.数组下标从零开始 4.ArrayList遍历删除时报错 5.字符转成数字的坑 6.while循环体的&q ...

  3. Java语言的十大特性

    Java语言的特性 总结了以下内容,希望有所帮助. --------------------------------------------- 1.简单 Java语言的语法简单明了,容易掌握从,而且J ...

  4. “坑爹”排行榜:Java语言最违反常识的功能点TOP 10

    来自:互联网全栈架构 作为一门面向对象的编程语言,Java凭借其简单易用.功能强大的特点受到了广大编程爱好者的青睐,伴随着开源社区的推波助澜,Java语言更是席卷全球,势不可挡,在世界各地都有Java ...

  5. 【网络安全入门大总结】—Java语言中常用的渗透漏洞大汇总

    Java语言中常用的漏洞大汇总,建议收藏. 准备好,上课了~~~ 目录 Servlet 简介 生命周期为 接口 Struts 2 . 简介 请求流程 相关CVE Spring 简介 Spring MV ...

  6. Java9发布回顾Java 8的十大新特性

    java9已经在北京时间9月22日正式发布,开发者可以在oracle jdk官网上下载到最新的jdk9. 今天,我们先来一起复习一下2014年发布的Java 8的十大新特性.先来喝杯java~~~ 按 ...

  7. [转载] Java9发布回顾Java 8的十大新特性

    参考链接: Java中的DoubleStream mapToObj() java9已经在北京时间9月22日正式发布,开发者可以在oracle jdk官网上下载到最新的jdk9. 今天,我们先来一起复习 ...

  8. python十大语言_Python语言的十大神器

    本文主要向大家介绍了Python语言的十大神器,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. 相传在上古时期,混沌未分,鸿蒙初现,天地间产生十件威力无比的神器,分别是:东皇钟.轩 ...

  9. java语言中声明布尔型_【Java初探02】——Java语言基础

    本篇博文就Java语言的一些基本元素进行一些记录和阐述,主要讲解一下Java语言的一些基本构成元素和Java的主类结构. Java语言基础的大致组成 java主类结构 基本的数据类型 变量与常量 运算 ...

最新文章

  1. sys.argv[]学习
  2. win7 重启 IIS.
  3. opencv表面缺陷检测_彩钢板表面缺陷在线检测--Smart Vision
  4. JavaCC首页、文档和下载 - 语法分析生成器 - 开源中国社区
  5. 目标和(01背包应用)
  6. ICDAR 2019国际竞赛召开在即,百度联合学界重奖破局者!
  7. Lintcode Subarray Sum Closest
  8. 《机器学习》 周志华学习笔记第八章 集成学习(课后习题)python实现
  9. 巧用计算机教授小学英语,巧用微课构建小学英语课堂教学
  10. 浅谈 System.Linq.Enumerable.AsEnumerable 方法
  11. Cisco Packet Tracer安装教程
  12. 在spss中实现变量标准化Z值
  13. JavaSE——多线程
  14. 如何通过 User-Agent 识别百度蜘蛛
  15. python语句中print(type(1j))_Python语句 print(type(1/2))的输出结果是:______
  16. dp在约会上是什么意思_饭圈用语dp是什么梗
  17. 江苏在职读研计算机专业,计算机技术专业江苏科技大学在职研究生的相关信息介绍...
  18. linux内核工程导论,Linux内核工程导论–网络:TCP:netlink与tcp_diag编程
  19. VBA中的正则表达式(一)
  20. 一亩三分地 每日答题

热门文章

  1. golang 结构体和数据库表字段 反射自动映射 sqlmapper库 简介
  2. linux 检测 iptables 是否有重复的规则
  3. centos7 xfce 中文字体输入法
  4. golang 字符串比较 不区分大小写
  5. linux namespace 隔离内核资源的方式 简介
  6. linux shell case语句
  7. linux给普通用户sudo权限
  8. linux centos7 docker 安装 oracle
  9. 找到合适的方案记录服务端日志
  10. linux 线程 pthread_create 源码 剖析