转型操作并不改变对象在内存的形式

 1 /*
 2     需求:设计一个简单的java程序,证明强制转换语句并不能改变其在内存中的形式
 3     思路:设计一个父子类,创建子类对象,将子类向上转型,查看转型前后该对象在内存中是否发生变化
 4 */
 5
 6 class  ExchangeTest
 7 {
 8     public static void main(String[] args)
 9     {
10         Child c = new Child(23);
11         System.out.println(c);
12         Father f = (Father)c;
13         c.show();
14         f.show();
15         System.out.println(f);//c和f都是指向了内存中同一个对象,且该对象是Child的实例对象
16     }
17 }
18
19 class Father
20 {
21     int worknum;
22     Father(int i){
23         worknum = i;
24     }
25     void show(){
26         System.out.println("Father " + worknum);
27     }
28 }
29
30 class Child extends Father
31 {
32     int studynum;
33     Child(int i){
34         super(i);
35         studynum = i;
36     }
37     void show(){
38         System.out.println("Child " + studynum);
39     }
40 }
41
42
43 /*
44 总结:
45     将子类向上转型后,子类对象在内存中依旧是子类对象,即使一个父类变量指向该对象后,该对象依旧是子类对象。
46
47
48 运行时出现的bug
49 -----------------------------------------------------------------------------------
50 ExchangeTest.java:31: 错误: 无法将类 Father中的构造器 Father应用到给定类型;
51         Child(int i){
52                     ^
53   需要: int
54   找到: 没有参数
55   原因: 实际参数列表和形式参数列表长度不同
56 1 个错误
57
58 错误原因:   子类构造函数Child(int i){}中首行有个隐藏的默认语句super();该语句会调用
59             父类的空参构造函数,因为父类写了Father(int i){}  所以原来隐藏的Father(){}
60             没有了,因此子类构造函数中的super()找不到Father(){}  因此报错
61 -----------------------------------------------------------------------------------
62 */
结果:

  

总结:
   将子类向上转型后,子类对象在内存中依旧是子类对象,即使一个父类变量指向该对象后,该对象依旧是子类对象。
时间: 2024-10-10 23:48:09

转型操作并不改变对象在内存的形式的相关文章

黑马程序员---OC基础6【内存管理】【手动内存管理】【单、多个对象的内存管理】【*@property参数】【@class的使用】【NSString类的内存管理】【autorelease使用】

------- iOS培训.Android培训.Java培训.期待与您交流! ---------- [内存管理] 1.内存管理概念 由于移动设备内存及其有限,所以每个app所占的内存也是有限的 需要回收一些不使用的空间 2.OC内存管理的范围 管理任何继承NSOject的对象,对其他的基本数据类型无效 主要管理堆区中的对象的内存管理   3.内存管理的原理 1)对象所有权概念 任何对象都可以能拥有一个或多个所有者,只要一个对象至少还拥有一个所有者,他就会继续存在 cocoasu所有权策略 任何自

Effective C++ 条款27 尽量少做转型操作

1. 转型语法有三种, C风格转型:(T)expression 函数风格转型:T(expression) 两种方式除了小括号位置不同没有差别,可以称为"旧式转型". C++提供四种新式转型: const_cast<T>(expression): 将const变量引用或指针转为非const引用或指针,移除变量的常量特性.T必须是指针或引用. 注:虽然经const_cast转型后的变量可以被更改,但由于"常量折叠"(c++编译器在编译时将const 变量替换

对象的内存布局

对象内存布局 在Hotspot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头,实例数据,对齐填充. 1.对象头 1.1 存储对象自身的运行时数据(mark word):哈希码,gc分代年龄. 1.2 Class指针:通过该指针确定该对象是哪个类的实例. 在64位系统中,class指针占4B,mark word在开启指针压缩的时候占4B;未开启指针压缩的时候占8B. 在32位系统下,上面两部分各占4B; 2.实例数据 默认分配策略:long/double ->  int/float ->

Java对象的内存布局以及对象的访问定位

先来看看Java对象在内存中的布局 一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储对象自身的运行时数据,包括哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时 间戳等 类型指针 即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.但是并不是所有类型虚拟机实现都必须在对象数据上保留类型指针,如果对象是一

JVM内存模型及对象在内存中初始化的过程

JVM内存模型 Java虚拟机所管理的内存区域,也称为运行时数据区,分为以下几个运行时数据区,如图所示 程序计数器:当前程序所执行字节码的行号指示器 程序计数器(Program Counter Register)是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选 取下一条需要执行的字节码指令,分支.循环.跳转.异常处理.线程恢复等基础功能都需 要依赖这个计数器来完成. Java虚拟机的多线程是是通过线程轮流切

39-oc集合中对象的内存管理

集合中对象的内存管理 集合的内存管理原则是什么 当把一个对象添加到集合中时,这个对象会做了一次retain操作,计数器会+1 当一个集合被销毁时,会对集合里面的所有对象做一次release操作,计数器会-1 当一个对象从集合中移除时,会对这个对象做一次release操作,计数器会-1 集合方法的普遍规律是什么 如果方法名是add\insert开头,那么被添加的对象,计数器会+1 如果方法名是remove\delete开头,那么被移除的对象,计数器-1

PHP面向对象(PHP对象在内存中的分配)

对 像在PHP 里面和整型.浮点型一样,也是一种数据类,都是存储不同类型数据用的, 在运行的时候都要加载到内存中去用,那么对象在内存里面是怎么体现的呢?内存从逻 辑上 说大体上是分为4 段,栈空间段.堆空间段.代码段.初始化静态段,程序里面不同的声明 放在不同的内存段里面,数据段(data segment)通常是指用来存放程序中已初始化且不为0的全局变量如:静态变量和常量:代码段(code segment / text segment)通常是指用来存放程序执行代码的一块内存区域,比如函数和方法:

小白学开发(iOS)OC_ 单个对象的内存管理(2015-08-02)

// //  main.m //  单个对象的内存管理 // //  Created by admin on 15/8/3. //  Copyright (c) 2015年 admin. All rights reserved. // #import <Foundation/Foundation.h> #import "Person.h" void test(); void test5(Person * p); int main(int argc, const char *

PHP对象在内存中的分配

在网上看到一篇关于php对象在内存中分配的博文,特地记录下来,再稍微修饰下. 对像在PHP 里面和整型.浮点型一样,也是一种数据类,都是存储不同类型数据用的, 在运行的时候都要加载到内存中去用,那么对象在内存里面是怎么体现的呢? 内存从逻 辑上 说大体上是分为4 段,栈空间段.堆空间段.代码段.初始化静态段,程序里面不同的声明 放在不同的内存段里面. 数据段(data segment)通常是指用来存放程序中已初始化且不为0的全局变量如:静态变量和常量: 代码段(code segment / te