Java虽开发效率低下,但架不住其构建的系统稳定、移植性好、开源框架及可用轮子丰富,这么多年来仍是构建大型系统首选语言,因此其在每期的编程语言排行榜都是位列前茅,在众多java开发者中,不排除技术大咖、老鸟,同时也有大量java初学者。本文汇总了Java开发过程中曾经踩过的坑和易犯错误,旨在给java初学者提个醒。
文章更新说明:
日期 | 更新说明 |
2019-08-24 | 新建 |
2019-08-25 | 增加算数运算隐形类型转换说明 |
1、自动装箱、拆箱与常量池
1)int, long等非String类型
先看个案例:
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer aa = new Integer(1);
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println(a == aa); //false,a指向常量池地址,aa新开辟了内存空间
System.out.println(c == d); // true
System.out.println(e == f); // false,超出[-128,127],e和f都新开辟内存空间
System.out.println(c == (a + b)); // true,a+b运算自动拆箱成int进行运算,运算结果隐性转换为long类型
System.out.println(c.equals(a + b)); // true
System.out.println(g == (a + b)); // true
System.out.println(g.equals(a + b)); // false, 不是同一类型
System.out.println(g.equals((long) (a + b))); // true
}
案例说明:
- 对于Integer,java内置创建了[-128,127],谓之常量池,因此Integer c = 3和Integer d = 3指向同一内存地址,故c==d 输出true
- c == (a + b),a+b运算自动拆箱成int进行运算,运算结果隐性转换为long类型,由于有基本类型则比较值是否相等,3==3,故输出true
2)String类型
String类型自动装箱、拆箱及常量池略显复杂,先看个Demo:
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = "ab"+"c";
String s4 = new String("abc");
System.out.println(s1==s2); //true, s2对应的“abc”在常量池中已经存在,所以直接返回,故s1和s2指向同一地址
System.out.println(s1==s3); //true, s3得到的拼接字符串"abc"在常量池中已经存在,故输出true
System.out.println(s1==s4); //false, s4新开辟内存空间,和s1指向不同内存地址,故输出false
String s5 = "c";
String s6 = "ab" + s5; //变量相加,先开辟新空间
System.out.println(s1==s6); //s6指向新内存空间,故输出false
}
字符串是常量,它的值在创建之后不能更改。程序中所有字符串值(如 “abc” )都作为String的实例实现。
- 字符串如果是变量相加,先开空间,再拼接。
- 字符串如果是常量相加,是先拼接,然后在常量池找,有就直接返回,否则创建。
2、算数运算类型提升、隐形类型转换
先看个DEMO
public static void main(String[] args) {
short s = 1;
s = s + 1; // 报错,Type mismatch: cannot convert from int to short
// 正解,s = (short)(s + 1);
short s2 = 1;
s2 += 1;
System.out.println("s: " + s);
System.out.println("s2: " + s2);
}
代码说明:
- s = s + 1,由于1是int,因此s+1运算时先将s提升为int,从而整个表达式s+1得到的也是int,int赋值给short类型,所以就报错类型不匹配;
- s2 += 1 可以正确执行,其等同s2 = (short) (s2+1),有个隐藏的强制类型转换
3、char类型初始化值问题
char初始值为0, 表示空字符串,参考thinking的一个demo
public class InitValues {
boolean t;
char c;
byte b;
short s;
int i;
long l;
float f;
double d;
InitValues reference;
void printInitValues() {
System.out.println("Data type initial value ");
System.out.println("boolean " + t);
System.out.println("char [" + c + "]");
System.out.println("(int)char " + (int)c);
System.out.println("byte " + b);
System.out.println("short " + s);
System.out.println("int " + i);
System.out.println("long " + l);
System.out.println("float " + f);
System.out.println("double " + d);
System.out.println("reference " + reference);
}
public static void main(String[] args) {
new InitValues().printInitValues();
}
}
/* Data type initial value
boolean false
char []
(int)char 0
byte 0
short 0
int 0
long 0
float 0.0
double 0.0
reference null */