商丘天气-吐槽:那些Java规划中不得不说的槽点

1. 求长度各有千秋

你是否曾经在面试的时分,常常被问到:数组有没有 length() 办法?字符串有没有 length() 办法? 调集有没有 length() 办法?

面临这个问题,那么不得不吐槽一下,Java 中获取长度的办法,规划着实有点乱,对刚入门的程序猿而言,那肯定是一脸的懵逼。

String[] array = {"abc", "def"};
String str = "abcedf";
List list = new ArrayList();
list.add("abc");
list.add("def");
System.out.println("数组的长度: " + array.length);
System.ou商丘天气-吐槽:那些Java规划中不得不说的槽点t.println("字符串的长度: " + str.length());
System.out.println("调集的长度: " + list.size());

正式科普一下,期望能够铭记你心中。数组求长度用 length 特点;字符串求长度用 length() 办法;调集求长度用 size() 办法。

2. 字符串截取有深意

关于程序猿来说,编程标准能够养成杰出的编程习气,进步代码质量,削减交流本钱。阿里 Java 开发手册编程规约中记载,【强制】办法名、參数名、成员变量、局部变量都一致运用 lowerCamelCase 风格,有必要遵照驼峰方式。

看到这儿,不得不提 String 中的 substring 办法,你是不是常常把“substring”写成“subString”。本次这个命名不是吐槽的要点。主要想共享如下代码片段。

public class StringInterview商丘天气-吐槽:那些Java规划中不得不说的槽点 {
public static void main(String[] args) {
String str = "......abcdefgh.......";
String subStr = str.substring(1,3);
str = null;
System.out.println(subStr);
}
}

假设上述这段程序在 Java 1.6 中运转,代码中尽管强制使 str 引证为空,原意是开释 str 占用的空间,可是这个时分,GC 是无法收回这个大的 char 数组的,因为还在被 subStr 字符串内部引证着,尽管 subStr 只截取这个大数组的一小部分。当 str 是一个十分大字符串的时分,这种糟蹋是十分显着的,甚至会带来内存走漏问题。

深化 Java 1.6 中 substring 的规划一探终究。

public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
。。 。。 。。
}
if (endIndex > count) {
。。 。。 。。
}
if (beginIndex > endIndex) {
。。 。。 。。
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}

到此你应该拨云见日恍然大悟。当咱们调用字符串 str 的 substring 得到字符串 subStr,其实这个操作,无非便是调整了一下 subStr 的 offset 和 count ,用到的内容仍是 str 之前的 value 字符数组,并没有从头创立新的专归于 subStr 的内容字符数组。假如 subStr 的生命周期要善于 str 或许手动设置 str 为null,当废物收回进行后,str 被收回掉,subStr 没有收回掉,那么内存占用仍旧存在,因为 subStr 持有 str 字符数组的引证。

正式科普一下,这个问题出现在 Java 1.6,而且 Java 1.7 中现已修正。尽管现已修正,并不代表咱们就不需求了解,假如你正在求职路上,略微了解一下,说不定会加分。

3. 一条 if 句子引发不满

先给各位抛一段 Java LinkedList 类的代码片段,一同吐槽吐槽。

public E getFirst() {
final Node f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}

JDK 中 if 句子后只要一条句子,大部分都是这么完成的。原则上,if 句子假如后边跟着只要一句话,是能够不加的。可是在咱们实践开发中,有些现象却会让你匪夷所思,不信你看看下面的代码片段。

片段一

if (f == null)
//抛出反常,或许加一条打印句子,加上此句注释逻辑就变了
throw new NoSuchElementException();

片段二

public class Interview {
public static void main(S商丘天气-吐槽:那些Java规划中不得不说的槽点tring[] args) {
Class c = Interview.class;
try {
Object o = c.newInstance();
if (o instanceof Interview)
Interview t尿素t = (Interview) o; //为什么会报错?请各位解说原因
} catch (Exception e) {
e.printStackTrace();
}
}
}

正式科普一下,看似一个简略的编码标准,背面躲藏了多少坑啊,所以为了杰出的编程习气,主张仍是一致加上大括号为好,杰出的编码习气是真重要啊。

4. 时刻完成也找茬

Tiago Fernandez 做过一次投票,推举最烂的 Java API,排第二的便是日期 API(Date 和Calender)。一言不合就抛代码,如下片段是核算两个日期之间的天数。

public static void main(String[] args) {
Calendar begin = Calendar.getInstance();
begin.set(1990, Calendar.JUNE, 17);
Calendar end = Calendar.getInstance();
System.out.println(alculatedDays(begin, end));
System.out.println(alculatedDays(begin, end)); // 为什么显现 0?
}
public static long alculatedDays(Calendar begin, Calendar end) {
long days = 0;
while (begin.before(end)) {
begin.add(Calendar.DAY_OF_MONTH, 1);
days++;
}
return days;
}

alculatedDays 办法,假如接连核算两个 Date 实例的话,第2次会获得 0,因为 Calendar 状况是可变的,考虑到重复核算的场合,最好仿制一个新的 Calendar,改造如下

public static long alculatedDays(Calendar begin, Calendar end) {
Calendar calendar = (Calendar) begin.clone(); // 仿制
long days = 0;
while (calendar.before(end)) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
days++;
}
return days;
}

不过万物都在向前进化,因为因为本来老旧的日期 API 一向被人诟病,所以 JDK 1.8 中对日期的改动是特别大的,基本上是引入了一套全新易用的 API,各位有时刻能够体会一下。

好了,吐槽中见真理,今日就讲这么多吧。期望你能 get 到一点点共识,假如你比较感兴趣,就多多重视和共享给身边的朋友吧