注意: 引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所 具有的方法。因此,编写Java代码 时,引用变量只能调用声明该变量时所用类里包含的方 法。 例如, 通过Object p=new Person()代码定义一个变量p,则这个p只能调用 Object类的方 法,而不能调用Person类里定义的方法。 注意: 通过引用变量来访问其包含的实例变量时,系统总是试图访问 它编译时类型所定义的 成员变量,而不是它运行时类型所定义的成 员变量。引用变量的强制类型转换 编写Java程序时,引用变量只能调用它编译时类型的方法,而不能调用它运行时类型的方法, 即使它实际所引用的对象确实包含该方 法。如果需要让这个引用变量调用它运行时类型的方法, 则必须把它 强制类型转换成运行时类型,强制类型转换需要借助于类型转换运算 符。 类 型 转 换 运 算 符 是 小 括 号 , 类 型 转 换 运 算 符 的 用 法 是 :(type)variable,这种用 法可以将variable变量转换成一个type类型 的变量。前面在介绍基本类型的强制类型转换时,已经 看到了使用这 种类型转换运算符的用法,类型转换运算符可以将一个基本类型变量 转换成另一个 类型。
除此之外,这个类型转换运算符还可以将一个引用类型变量转换成其子类类型。这种强制类 型转换不是万能的,当进行强制类型转换 时需要注意: ➢ 基本类型之间的转换只能在数值类型之间进行,这里所说的数 值类型包括整数型、字符型和浮点型。但数值类型和布尔类型 之间不能进行类型转换。 ➢ 引用类型之间的转换只能在具有继承关系的两个类型之间进 行,如果是两个没有任何继承关系的类型,则无法进行类型转 换,否则编译时就会出现错误。如果试图把一个父类实例转换 成子类类型,则这个对象必须实际上是子类实例才行(即编译 时类型为父类类型,而运行时类型是子类类型),否则将在运 行时引发ClassCastException异常。
下面是进行强制类型转换的示范程序。下面程序详细说明了哪些情况可以进行类型转换,哪些情况 不可以进行类型转换。
考虑到进行强制类型转换时可能出现异常,因此进行类型转换之前应先通过instanceof运算符来判 断是否可以成功转换。例如,上面 的var str=(String)objPri;代码运行时会引发 ClassCastException 异常,这是因为objPri不可转换成String类型。为了让程序更加健 壮,可以将 代码改为如下: 在进行强制类型转换之前,先用instanceof运算符判断是否可以成功转换,从而避免出现 ClassCastException异常,这样可以保证程 序更加健壮。
注意: 当 把 子 类 对 象 赋 给 父 类 引 用 变 量 时 , 被 称 为 向 上 转 型(upcasting),这种转型 总是可以成功的,这也从另一个侧面证实 了子类是一种特殊的父类。这种转型只是表明这个 引用变量的编译 时类型是父类,但实际执行它的方法时,依然表现出子类对象的行 为方式。 但把一个父类对象赋给子类引用变量时,就需要进行强制 类型转换,而且还可能在运行时产 生ClassCastException异常,使 用instanceof运算符可以让强制类型转换更安全。instanceof和类型转换运算符一样,都是Java提供的运算符,与+、-等算术运算符的用法大致相 似,下面具体介绍该运算符的用法。
instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(也可以 是接口,可以把接口理解成一种特 殊的类),它用于判断前面的对象是否是后面的类,或者其子 类、实 现类的实例。如果是,则返回true,否则返回false。 在使用instanceof运算符时需要注 意:instanceof运算符前面操 作数的编译时类型要么与后面的类相同,要么与后面的类具有父子 承 关系,否则会引起编译错误。下面程序示范了instanceof运算符的 用法。
上面程序通过Object hello="Hello";代码定义了一个hello变量,这个变量的编译时类型是Object 类,但实际类型是String。因为 Object类是所有类、接口的父类,因此可以执行hello instanceof String和hello instanceof Math等。 但如果使用var a="Hello";代码定义的变量a,就不能执行a instanceof Math,因为编译器会推断出a 的编译类型是String, String类型既不是Math类型,也不是Math类型的父类,所以这行代码 编译就 会出错 instanceof运算符的作用是:在进行强制类型转换之前,首先判断前一个对象是否是后一个类的实 例,是否可以成功转换,从而保证 代码更加健壮。 instanceof和(type)是Java提供的两个相关的运 算符,通常先用 instanceof判断一个对象是否可以强制类型转换,然后再使用(type) 运算符进行强 制类型转换,从而保证程序不会出现错误



