1. 对象创建和实例化
java中的变量分为基本类型变量和对象,基本类型包括:boolean、byte、short、int、long、char、float和double,声明后可以直接使用。声明对象后不能直接使用,必须new创建或者通过方法调用返回。
例如:
Vector v;
int count = v.size();
的用法是不正确的,因为对象v还没有创建,没有被赋值(初始化)。正确的用法是:
Vector v;
v = new Vector();
int count = v.size();
通过方法调用得到对象的例子:
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
有人要问,对于java的内置类String,也可以声明后不直接使用啊,例如:
String s;
s = "how about ee2ee?";
其实,在使用字符串"how about ee2ee?"时,系统已经为这个字符串创建String对象了,系统将其翻译成如下语句:
String s;
s = new String("how about ee2ee?");
对于数组对象,也是同样的道理,例如:
int[] i = new i[3];
i[0] = 1;
i[1] = 2;
i[2] = 3;
和
int[] i = {1, 2, 3};
是等价的。显然,后一种写法更简洁明了。
2. 子类对象和父类对象的相互转换
在面向对象中,子类对象可以直接赋给父类对象,而父类对象却不能直接赋给子类对象。有父类ParentClass和子类ChildClass:
ParentClass p;
ChildClass c = new ChildClass();
p = c; //正确,子类对象可以赋给父类对象
c = p; //编译错误,父类对象不能直接赋给子类对象
ParentClass p = new ParentClass();
c = p; //编译错误,父类对象不能直接赋给子类对象
c = (ChildClass)p; //运行错误,类型转换异常,因为p是父类的实例化对象,而不是子类ParentClass的实例化对象
p = new ChildClass(); //正确,子类对象可以赋给父类对象
c = (ChildClass)p; //正确,因为p指向的就是ChildClass的实例化对象
3. 子类对象数组和父类对象数组的相互赋值
子类对象数组可以直接赋值给父类对象数组,反之则不然。例如,有父类ParentClass对象数组ps和子类ChildClass数组cs:
ParentClass[] ps;
ChildClass[] cs = new ChildClass[10];
ps = cs; //正确
ps = new ParentClass[10];
ChildClass[] cs;
cs = ps; //编译错误
ps = new ChildClass[10];
cs = (ChildClass[])ps; //编译通过,但运行时出现类型转换异常
对于最后一种情况,应使用System.arraycopy把一个数组中的元素赋值到另外一个数组。以上的最后一行代码应改写如下:
System.arraycopy(ps, 0, cs, 0, ps.length);
4. java中的byte类型问题
byte类型占用1个字节的存储单元,其取值范围为-128 ~ +127。在二进制流处理中,如何把一个byte变量的值转换为0 ~ 255的无符号整数呢,可以通过如下样例代码实现:
byte b = -10;
int i;
if (b < 0)
{
i = b + 256; //转换为对应的无符号整数
}
else
{
i = b;
}
5. java中的数据精度问题
有如下代码:
int i = 1000000;
long l = i * 1000000;
System.out.println(l);
请问,程序运行的输出结果是什么?
如果回答1000000000000,那就错了!输出的结果是一个负数:-727379968!
为什么会出现这样的异常现象呢?这需要使用java的类型转换机制来解释。java中,低精度类型可以赋值给高精度类型,例如:int变量可以直接赋值给long变量,反过来需要进行强制类型转换(可能会导致数据精度丢失)。上例中,变量i为int类型,关系式:
long l = i * 1000000;
对于后面的常量1000000,java会将其解释为int类型,int类型 + int类型,运算结果仍为int类型,导致了数据精度的丢失。在赋值给long变量l之前,精度已经丢失了。