对Java的几点思考

1. 符号带来的问题

我们知道,Java里的整数类型——byte,short,int——全部是有符号的。这有时会带来麻烦,如果我们并不想要最高位作为符号位的话。

下面是两个例子:

a) 我们不得不这样做来正确显示IP地址:

byte[] ipa;
InetAddress ina = CmdSocket.getLocalAddress();
ipa = ina.getAddress();
for (int i=0; i< 4; i++) {
System.out.println(((int)ipa[i]) & 0xff);
}

b) 记住,char是无符号的:[1]

public class Multicast {
public static void main(String[] args) {
System.out.println((int) (char) (byte) -1);
}
}

2. 类型问题

Java在处理类型之间转化时有着自己的规则,这些规则有时并不好理解。

a. 转化[2]

short x = 0;
int i = 123456;
x += i;
x = x + i; //<== fails here

b. 溢出[3]

public class LongDivision {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 60 60 1000 1000;
final long MILLIS_PER_DAY = 24 60 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}

3. 读文件的问题

Java中有各种各样的流,这使得选取恰当的流并不容易。有时,我们为了得到一个理想的流,不得不转化多次:

BufferedOutputStream FTPOutStream;
FTPOutStream = new BufferedOutputStream((OutputStream)System.out);
BufferedInputStream FTPInStream;
FTPInStream = new BufferedInputStream(new FileInputStream(LocalFile));

而且,Java中的DataInputStream流并不像想象中那么好,根本原因是:readInt()并不认识int,它只管读下面4个字节,并不在乎它这四个到底是什么,即使在文本中它们看起来可能只是几个非数字的字符!同样,readLong不认识long,readDouble()也不认识double。而这一点,C++和C做得明显要更好。

Scanner或许可以帮上一些忙,不过很可惜,你不能用它读一个char!


参考资料:

[1][2][3]均摘自《Java Puzzlers》
[4]《Java Language Specification》