Java向上转型及内存分析

逻辑星芒
• 阅读 3863

学习设计模式的时候,发现很多模式都用到了向上转型(eg. 工厂方法)。而我对向上转型(upcasting)的机制并不十分熟悉。这篇文章将深入分析向上转型的机制、内存分析。

概念

先从几个基本概念开始:

1. Java中的引用类型(reference type)

Java中的数据类型分为两类:基本数据类型(int, double)和引用类型(String)。引用类型对象中保存着一个地址(称为“引用”),引用指向实际对象(称为“实例”),实际对象中保存着值。

关于Java数据类型在内存中的分析详解,请参考知友Intopass的解答:

Java 到底是值传递还是引用传递? - Intopass的回答 - 知乎
https://www.zhihu.com/questio...

2. 内存分配

Java向上转型及内存分析

Heap中的对象会继续指向内存中的数据段(data segment)。数据保存对象的实际值

3. 向上转型

定义:将父类的引用指向子类的实例 or 将子类对象赋值给父类引用

Dog dog = new Dog();
Animal anim = (Animal) dog; //实际对象类型没变,仅引用类型改变了
anim.eat();

由于实际对象类型没变,所以,anim调用的eat方法仍是Dog类中重写的eat方法,而不是父类Animal类中的eat方法。

用途

我们为什么要使用向上转型?

Generally, upcasting is not necessary. However, we need upcasting when we want to write general code that deals with only the supertype.

一般说来,向上转型不是必须的。但有时候,当我们的代码只需要与父类打交道时,可以使用向上转型,来使我们的代码不依赖具体子类,比如:

public class AnimalTrainer {
    public void teach(Animal anim) {
        anim.move();
        anim.eat();
    }
}

以下代码,teach方法可以接受Animal类的任意子类:

Dog dog = new Dog();
Cat cat = new Cat();
 
AnimalTrainer trainer = new AnimalTrainer();
trainer.teach(dog);
trainer.teach(cat);

内存分析

我们来分析以下转型代码在内存中的表示:

Dog dog = new Dog();
Animal anim = (Animal)dog;

Java向上转型及内存分析

点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
Wesley13 Wesley13
4年前
java向上转型和向下转型1
  在java继承体系中,认为父类(超类)在上层,子类在下层(派生类),向上转型就是把子类对象转成父类对象。1publicclassFather{2publicvoideat(){3System.out.println("我是父类的方法吃。。。。。");4}
Wesley13 Wesley13
4年前
Java中ArrayList的向上转型问题(父类与子类的关系)
果然是java都没学好,今天写方法的时候想把方法参数写成List<父类,然后传子类进去统一处理,结果发现报错。丢人地百度了:ArrayList<ChildClass();包括泛型在内的整个作为类型是无法强转成ArrayList<FatherClass 如果想这样使用可以使用extends关键字来限制泛型参数的适用范围 List<T
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
4年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
Java 多态
类型的检测——向上转型向下转型向上转型:父类对象的引用指向子类对象,向下转型:向上转型的基础上再次指向子类的对象1.向上转型!(https://oscimg.oschina.net/oscnet/dd0d05d39a724e781b799ff5e35b921775d.jpg)!(https://oscimg.oschina.net/o
Easter79 Easter79
4年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
4年前
Java基础学习总结(4)——对象转型
一、对象转型介绍!(http://static.oschina.net/uploads/img/201512/31130644_mPJ1.jpg)  对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型。转型的意思是:如把float类型转成int类型,把do