Skip to content
JAVA对其处理的信息非常苛刻。Java希望所有的事情都是确实的,它不能容忍任何可选的情况出现。

将参数传递给方法或在表达式中使用变量时,必须使用数据类型正确的变量。
如果方法要的是int,而您试图传递一个flaot值,Java编译器将报错

Java编译器在一个方面非常灵活:String对象。拼接运算符(+)简化了方法println()、赋值语句和方法参数中字符串操作。如果被拼接的变量中有一个是字符串,则Java将所有内容都作为字符串进行处理。

有时,Java程序中某个值的类型并非您所需要的,在这种情况下,可以通过强制类型转换将值从一种类型转换为另一种类型。

强制类型转换(casting)生成一个类型不同于源值的新值。
虽然强制类型转换的概念很简单,但使用起来却很复杂,这是由于Java即有基本数据类型(如int、float和boolen),又有对象类型(String、Point等)。

三种形式的强制类型转换:

基本数据类型之间的强制转换,如int到float,或float到double;

从一种类的对象强制转换为另一种类的对象,如从Object转换为String;

从基本数据类型强制转换为对象,然后从对象中提取出基本类型值。

**强制转换基本类型**
基本类型之间的强制转换通常发生在数字类型上。

布尔类型值要不为true,要么为false,不能用于强制类型转换操作中。

在许多基本类型间的强制转换中,目标可以保存比源更大的值,因此转换起来很容易。例如将byte转换为int。

通常将byte或char用作int,将int用作long或float,将任何数字类型用于double。在大多数情况下,由于更大的数据类型的精确度比小类型高,所以不会导致信息丢失。一种例外情况是将整数转换为浮点数。将long转换为float或将long转换为double都可能精度降低。

**注意:**字符可以用作int,因为每个字符都有相应的数字编码,它表示该字符在字符集中的位置。如果变量key的值为65,则强制类型转换(char)key的结果为字符A。在ASCii字符集,A对应的数字编码是65。这种字符集是Java支持字符中的一部分。

将大类型值转换为小类型值时,必须显式地进行强制类型转换,否则将导致精度降低。
显式强制类型转换的格式如下:
(typename) value
其中typename是目标数据类型,如short、int或float。value是表达式,其结果为要转换的源类型。如,在下面的例子中,x被y除后的结果被强制转换为int类型:
int result = (int)(x/y);

注意,由于强制类型转换的优先地级高于算术运算,所以这里必须使用圆括号。

**强制转换对象**
类的对象也可被转换为其他类的对象,但必须满足如下条件:源类和目标类之间存在继承关系,即其中一个是另一个的子类。

与将基本类型转换为更大类型相似,有些对象无须显式地转换。具体地说,由于子类包含超类的所有信息,因为可以在任何期望超类的地方使用子类对象。

反过来也是如此,可以在需要子类的地方使用超类。然而有一个问题:由于子类的行为比超类多,所以将降低精度。超类对象可能不具备子类对象的所有行为。

例如,如果在调用Integer对象的方法的地方使用其超类Number的对象,而Number对象没有很多Integer特有的方法。试图调用目标对象同有的方法将出错。

要在需要子类对象的地方使用超类对象,必须显式地进行强制类型转换。在转换过程中,不会损失任何信息,而是得到了子类定义的全部方法和变量。要将对象强制转换为另一种类,需要使用与基本类型相同的操作:
(classname) object
其中classname 是目标类的名称,object 是源对象的引用;强制类型转换创建一个classname对象的引用;原来的对象继续存在。

下面的示例将类VicePresident的一个实例强制转换为类Employee的实例。VicePresident是Employee的子类,包含更多信息:
Employee emp = new Employee();
VicePresideng veep = new Vicepreideng();
emp = veep;
veep = (VicePresideng)emp;

除强制转换为某种类外,还可以将对象强制转换为接口,但仅当该对象的类或其超类之一实现了该接口才行。将对象强制转换为接口意味着您可以调用该接口的方法,即使该对象的类并没有实现这个接口。

**基本类型和对象之间的转换**
在任何情况下,都不能将对象强制转换为基本数据类型或将基本类型强制转换为对象。

在Java中,基本类型和对象是完全不同的东西,不会自动在它们之间进行转换。

Java.lang包中包含了对应于每种基本数据类型的类:Float, Boolean, Byte等。这些类大多数与数据类型的名称相同,只是类名首字母大写。而有两个类的名称与对应数据类型不同,即分别对应char和int变量的Character和Integer。

使用每个基本类型对应的类,可以创建存储相同值的对象。下面的语句创建了类Integer的一个实例,其值为7801:
Integer dataCount = new Integer(7801);
使用这种方式创建对象后,可像使用其他对象那样使用它(虽然不能修改它的值)。当您想将它作为基本类型值使用时,也有用于实现这种目的的方法。例如,要从对象dataCount获得一个int值,可以使用下面的语句:
int newCount = dataCount.inValue();
在程序中,常常需要将字符串转换为数字类型,如整数类型。需要int结果时,可以使用Integer类的类方法parseInt()来实现。
String pennsylvania = "65000";
int penn= Integer.parseInt(pennsylvania);

下面的类用来处理对象,而不是基本数据类型:
Boolean, Byte, Character, Double, Float, Integer, Long, Short和Void。
这些类通常被称为对象封装器(object wrapper),因为它们提供了基本类型值的对象表示。

如果您在程序中使用上述代码,该程序将无法通过编译。如果参数不是合法的数值,paresInt()将发生NumberFormatException错误。为了处理这种错误,必须通过使用特殊的错误处理语句。

通过自动封装(autoboxing)和拆封(unboxing)——一种自动转换过程,处理表示同一类值的基本类型和对象时更为容易。

自动封装自动地将基本类型转换为对象,而拆封执行相反的操作。

如果编写语句时,在本应使用基本类型变量的地方使用了一个对象或相反,相应的值将被转换,以便语句能够被成功执行。
最初的几个Java版本没有提供这种功能。如:
Float f1 = 12.5F;
Float f2 = 27.2F;
System.out.println("Lower number:"+Math.min(f1,f2));
方法Math.min()接收两个float参数,但在上述实例中,给这个方法传递的是两个Float对象。编译器不会因为这种不一致而报错。相反,它将Float对象拆封为float值,再将其传递给min()方法;
**注意:**仅当对象包含值时才能对它进行拆封。如果没有调用构造函数来创建对象,编译将失败。

本站总访问 — 次