初学java时候有一个疑问,子类有父类没有的属性,子类强制转换为父类以后,再强制转换回来属性怎么还在?
比如代码:
Student s = new Student(); s.setName("张三"); Object o = s; System.out.println(o); Student s2 = (Student)o; System.out.println(s2);
有一个学生类,张三,把他强制转换成object,然后object竟然还有张三的属性,上面代码的测试结果:
name:张三 passwds:null node:null name:张三 passwds:null node:null
查阅资料后发现:
所有的java对象都是用引用指向真实的对象地址(内存中new出来的地址),类似指针,而这个引用的类型和实际的java内存对象的类型是不一定一样的,暂时叫他表面类型(没找到统一称呼)。
就像下面这个图
其实是object类型的引用,和student类型的引用,都指向的实际的,堆内存中的student对象。而用的时候,比如System.out.println,是用的堆内存中的实际对象,所以可以将原有信息打印出来。
另:如果子类强制转换到父类,如下代码:
Object o1 = new Object(); Student s3 = (Student)o1;
编译没有错误,运行时候会报错:
Exception in thread "main" java.lang.ClassCastException: codeTest.Person cannot be cast to codeTest.Student
java不支持向下转型。
java的instanceof关键字,比对的是堆的实际对象的类型,如下代码:
List<String> l = new ArrayList<String>(); System.out.println(l instanceof RandomAccess);
执行结果为true。
个人总结:
上面代码中,引用类型都是在编译期起作用的,实际类型都是在运行时起作用的,如printl打印的时候,使用instanceof比较的时候.父类引用可以指向一个子类的实际对象,但是子类的引用类型却不能指向父类的实际对象,所以运行时,jvm发现你强制把Student的引用指向object对象,就会抛错。