感冒咳嗽停更了几天,今天恢复更新了。

先来看下instanceof与向下转型的概念:

1.instanceof

instanceof是一个二元操作符,用法是:boolean result = a instanceof ClassA,即判断对象a是否是类ClassA的实例,如果是的话,则返回true,否则返回false。

2.向下转型

对于向上转型,笔记12已经说明过了,即父类对象引用指向了子类对象;向下转型是指,子类的对象引用被赋值为父类对象引用,并且赋值时要进行显式的强制类型转换,而该父类对象引用必须是指向子类对象的;向下转型最终还是子类对象引用指向了子类对象,也就是说,向上转型后,再通过向下转型变回来;向上转型后丢失的属性和方法经过向下转型又可见了。关于向下转型的意义,请参考http://blog.csdn.net/xyh269/article/details/52231944。

用文字描述起来比较绕口,看下面的式子就好理解了。记Person为父类,Student为子类。

    Person per = new Student(); //向上转型

    Student stu = (Student) per; //向下转型

由于per本来指向的就是子类对象,所以可以通过显式的类型转换使stu也指向该子类对象。

对于下面的语句,则不能进行向下转型:

Person per1 = new Person();

Student stu1 = (Student) per1;

会出现下面的错误:

Exception in thread "main" java.lang.ClassCastException: human.Person cannot be cast to human.Student
    at human.TestMain.main(TestMain.java:15)

因为per1指向的是父类对象,stu1是子类引用,而子类的属性数及方法数是大于父类的,所以是没法转换为子类对象的。

参考下面的内存图就比较直观了:

3.那么怎么判断能不能向下转型呢?

可以先用instanceof判断父类的对象引用是不是指向了子类的实例,是的话,则可以向下转型,否则就不可以。

作者: 蝉蝉

请尊重作者劳动成果,转载请在标题注明“转载”字样,并标明原文链接:

http://www.cnblogs.com/chanchan/p/7863173.html

4.下面是例子,代码如下:

package human;

public class TestMain {
public static void main(String[] args) { Person per = new Person();
Person per2;
Student stu = new Student();
Student stu2; per2 = stu;
stu2 = (Student) per2;
// stu2 = (Student) per; if( per2 instanceof Student )
System.out.println("per2指向的是Student类的对象");
else
System.out.println("per2指向的不是Student类的对象");
if( per2 instanceof Person )
System.out.println("per2指向的是Person类的对象");
else
System.out.println("per2指向的不是Person类的对象"); if( per instanceof Student)
System.out.println("per指向的是Student类的对象");
else
System.out.println("per指向的不是Student类的对象");
if( per instanceof Person )
System.out.println("per指向的是Person类的对象");
else
System.out.println("per指向的不是Person类的对象"); if( stu2 instanceof Student )
System.out.println("stu2指向的是Student类的对象");
else
System.out.println("stu2指向的不是Student类的对象");
if( stu2 instanceof Person )
System.out.println("stu2指向的是Person类的对象");
else
System.out.println("stu2指向的不是Person类的对象"); if( stu instanceof Student )
System.out.println("stu指向的是Student类的对象");
else
System.out.println("stu指向的不是Student类的对象");
if( stu instanceof Person )
System.out.println("stu指向的是Person类的对象");
else
System.out.println("stu指向的不是Person类的对象");
} }

输出结果如下:

 per2指向的是Student类的对象
per2指向的是Person类的对象
per指向的不是Student类的对象
per指向的是Person类的对象
stu2指向的是Student类的对象
stu2指向的是Person类的对象
stu指向的是Student类的对象
stu指向的是Person类的对象

结果分析:

(1).per2 = stu;

stu2 = (Student) per2;

per2与stu指向了同一子类对象,所以可以进行向下转型。

(2).// stu2 = (Student) per;

由于per指向的是Person类的对象,所以向下转型会出错。

(3).从1,2,5,6,7,8行输出可以看出,使用instanceof时,不论a定义为父类的对象引用还是子类的对象引用,只要最终指向的是子类对象,instanceof判定它既是父类的实例也是子类的实例即,可以看成子类实例包含了一个父类实例。

Java学习笔记15---instanceof与向下转型的更多相关文章

  1. Thinking In Java 学习笔记 1-5 章

    第1章 对象导论 本章主要讲OOP的思想及一些OOP基本概念 1.抽象过程:万物都是对象,对象具有状态.行为和标识.对象拥有属性和方法,以及在内存中的唯一地址. 2.每个对象都有一个接口:通过接口给对 ...

  2. Java学习笔记15

    do-while循环时while循环的变体语法如下:do{  // 循环体 语句(组);}while(循环继续条件); 如果循环中的语句至少需要执行一次,那么建议使用do-while循环. for循环 ...

  3. java学习笔记15(String 类,StringBuffer)

    /* * String类的特点: * 所有的""都是String的对象 * 字符串一旦创建就是常量,不能改变 */ public class StringDemo { public ...

  4. Java 学习笔记(15)——反射

    Java中的类文件最终会被编译为.class 文件,也就是Java字节码.这个字节码中会存储Java 类的相关信息.在JVM执行这些代码时首先根据 java 命令中指定的类名找到.class 文件然后 ...

  5. Java学习笔记15(面向对象八:匿名对象、内部类)

    匿名对象: 是指创建对象的时候,只有创建对象的语句,却没有把对象地址值赋给某个变量 创建一个普通对象: Person p = new Person(); 创建一个匿名对象: new Person(); ...

  6. java学习笔记之基础篇

    java选择语句之switch   //switch可以用于等值判断 switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字 ...

  7. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  8. 0035 Java学习笔记-注解

    什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...

  9. 20145330第九周《Java学习笔记》

    20145330第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JD ...

随机推荐

  1. MERGE语法详解

    merge语法是根据源表对目标表进行匹配查询,匹配成功时更新,不成功时插入. 其基本语法规则是 merge into 目标表 a using 源表 b on(a.条件字段1=b.条件字段1 and a ...

  2. 一个模型中有两个外键指向同一张表时,创建迁移模型时报错:“ HINT: Add or change a related_name argument to the definition for 'AnswersModel.author' or 'AnswersModel.relay_to'.”解决方案

    class AnswersModel(models.Model): author = models.ForeignKey(FrontUserModel,null=True,related_name=' ...

  3. java多线程编程核心技术——第七章补漏拾遗

    本章主要知识点: 1)线程组的使用 2)如何切换线程状态 3)SimpleDateFormat类与多线程的解决方法 4)如何处理线程异常. 这本书基本来到了终点,其实在第四章来说,核心(基础)的线程知 ...

  4. String类为什么要用final修饰(面试回答)

    String是所有语言中最常用的一个类.我们知道在Java中,String是不可变的.final的.Java在运行时也保存了一个字符串池(String pool),这使得String成为了一个特别的类 ...

  5. Asynchronous vs synchronous client applications(MQTT)

    来自我的CSDN博客   想查看英文原文的请点击原文网址.在上两篇翻译中,Homejim我给大家分别翻译了同步客户端应用程序和异步客户端应用程序.本人对这两个的区别也有困惑,因此将paho下的这个比较 ...

  6. SpringBoot里mybatis查询结果为null的列不返回问题的解决方案

    对于mybatis里查询结果为null的列不返回的问题解决方案 在配置文件application.properties里增加 Mybatis.configuration.call-setters-on ...

  7. python作用域与命名空间

    什么是命名空间 比如有一个学校,有10个班级,在7班和8班中都有一个叫“小王”的同学,如果在学校的广播中呼叫“小王”时,7班和8班中的这2个人就纳闷了,你是喊谁呢!!!如果是“7班的小王”的话,那么就 ...

  8. Django的设计模式

    MVC模式 MVC将应用程序分解为三个组成部分:mode(模型).view(视图).control(控制器),其中: M 管理应用程序的状态(通常存储到数据库中),并榆树改变状态的行为(或者叫&quo ...

  9. 简述ES6其他的东西

    第一是修饰器是ES7的一个提案,现在Babel转码器已经支持.那么什么是修饰器呢,修饰器是对类的行为的改变,在代码编译时发生的,而不是在运行时发生的且修饰器只能用于类和类的方法.修饰器可以接受三个函数 ...

  10. ES6之Symbol

    ES6中Symbol是为了防止属性名冲突而引入的,是独一无二的.Symbol值是通过Symbol函数生成.Symbol值不能与其他类型的值运算否则会报错且Symbol的值可以转换为字符串或者是布尔值但 ...