Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。
- 编译时类型由声明该变量时使用的类型决定。
- 运行时类型由实际赋给该变量的对象决定。
编译时类型和运行时类型不一致就会产生多态。
Object obj=new Integer(5);
obj是引用变量,他它有两个类型:
- 编译时类型:Object
- 运行时类型:Integer
引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法。因此,引用变量只能调用编译时类型里包含的方法。
例:Object p=new Person()
p只能调用Object类的方法,而不能调用Person类里定义的方法。
多态中的成员变量:
系统总是试图访问编译时类型所定义的成员变量
而不是它运行时类型所定义的成员变量
引用变量的强制类型转换:
- 基本类型之间的转换只能在数值类型之间进行,这里所说的数值类开型包括整型、字符型和浮点型。但数值类型和布尔类型之间不能进行类型转换。
- 引用类型之间的转换只能在具有继承关系的两个类型之间进行。如果是两个没有任何继承关系的类型,则无法进行类型转换,否则编译时会出错。
- 如果试图把一个父类实例转换成子类类型,则这个对象必须实际上是子类实例才行(即编译时类型为父类类型,而运行时类型是子类类型),否则将在运行时引发ClassCastException异常。例:
package unit5;
public class InstanceofTest
{
public static void main(String[] args)
{
Object obj=new Integer(5);
String str=(String)obj;
}
}
运行结果:
进行类型转换之前可以用Intanceof运算符凑数是否可以转换成功,再进行转换,从而避免出现ClassCastException异常,以此保证程序的健壮性。例:
Object obj="Hello";
if(obj instanceof String)
{
String str=(String)obj;
}
instanceof注意事项
instanceof运算符前面操作数的编译时类型要么与后面的类相同,要么与后面的类具有父子继承关系,否则会引起编译错误。
例:
String str="Hello";
//下条语句编译错误
//条件操作数类型 String 和 Math 不兼容
System.out.println(str instanceof Math);