java 运行 对象_java实例对象的编译时类型和运行时类型
为什么要区分编译时类型和运行时类型?
看这样一句代码:Person p=new Women()(Women类继承自Person类)那么,假如p的属性修饰符为public 访问属性时得到的是Person类的属性还是Women类的属性,方法调用又是哪个类?答案:会得到Person类的属性,调用Women类的方法。为什么会这样呢?这里就需要知道什么是编译时类型和运行时类型,Java程序状态会分为编译和运行这两种状态,编译时,JVM会在栈中静态创建基本数据变量,和引用数据变量的引用,回到刚刚那句代码,显然,p这个引用就是在编译时创建的,那么,p的编译时类型就是Person了,当运行这句java代码时,JVM在堆中为p新建一块内存,对应new Women()这句代码,所以p的运行时类型就是Women。有这样一条规则,对象调用编译时类型的属性和运行时类型的方法。下面先用代码表示这样的结果,然后再说明我个人的一些理解。
code1
public class TestDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p=new Women();
System.out.println("p.name:"+p.name);
p.show();
}
}
class Person{
public String name;
public Person()
{
name="person";
}
public void show()
{
System.out.println("class person's show()");
}
}
class Women extends Person
{
public String name;
public Women()
{
name="women";
}
public void show()
{
System.out.println("class women's show()");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
结果如下
从代码运行结果可以看出,p调用的属性属于Person类,而调用的方法是Women类的,验证了上面的规则–对象调用编译时类型的属性和运行时类型的方法
个人理解
这里属于我个人的理解,可能有错,以后发现会重新修正
根据上述规则
根据继承的特点我们可以知道,子类会继承父类非私有的属性和方法,也就是说,父类的(非私有)属性也会出现在子类中,当然,这是显而易见的,然而关键在于,如果子类重新定义了这一属性,会怎么样呢?实际上,父类的属性并不会被覆盖,为了方便起见,我把从父类继承来的属性记为–
属性 而自己重新定义的同名属性为–属性 这样,在子类中,会有两个属性 即:属性
属性,那么如何调用呢?–解答:<>中的内容对应着调用该属性的对象的编译时类型,编译时类型为父类,调用属性
,另一种情况就是调用子类的属性了。下面用图来表示:
Class
A中定义属性a,Class B继承自A,重新定义了属性a,此时,B中有编译时类型为A的属性a和编译时类型为B的属性a,Class
C继承自B,自己重新定义了属性a,这时,C具有三种编译时类型的属性a。这样就好看多了,不知道应该调用的属性是哪个类的,就只要分析自己的编译时类型就可以了,调用方法其实不用在意,直接调用运行时类型的方法即可(运行时类型还是比较容易看的)。
就上图的例子我们用代码测试如下
code2
public class TestDemo2 {
public static void main(String[] args) {
// 编译时类型为A,输出应该是A
System.out.println("编译时类型为A,输出应该是A");
A a=new A();
System.out.println(a.name);
A ab=new B();
System.out.println(ab.name);
A ac=new C();
System.out.println(ac.name);
// 编译时类型为B,输出应该是B
System.out.println("编译时类型为B,输出应该是B");
B b=new B();
System.out.println(b.name);
B bc=new B();
System.out.println(bc.name);
// 编译时类型为C,输出应该是C
System.out.println("编译时类型为C,输出应该是C");
C c=new C();
System.out.println(c.name);
}
}
class A
{
String name="A";
}
class B extends A
{
String name="B";
}
class C extends B
{
String name="C";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
运行结果如下
根据运行结果上述解释应该是合理的!
java 运行 对象_java实例对象的编译时类型和运行时类型相关推荐
- 浅谈Java异常及其编译时异常和运行时异常的区别
异常是程序编码和运行时经常发生的事件,了解异常有助于我们提高代码质量,增强系统的健壮性,这里总结一下Java编程中的异常.以及Java编译时异常和运行时异常的区别,并列举几种常见的异常,以供参考学习. ...
- java中的编译时异常和运行时异常
首先区分一下 编译时异常和运行时异常 运行时异常,也就是extends RuntimeException的异常编译时不用try{}catch(){}和throws 编译时异常,也就是extends E ...
- 异常---编译时异常和运行时异常:IO异常、NullPointerException、ArrayIndexOutBoundsException、ClassCastExoeption
一.概述 1.定义: 程序运行过程中的发生了不正常的情况 2.异常处理机制和作用----JVM虚拟机打印的 java语言时很完善的语言,提供了异常处理方式,出现异常,将异常信息打印到输出控制台,供程序 ...
- 编译时类型和运行时类型到底是什么?
最近在看多态,里面有一句话困扰了我很久,就是 编译时类型和运行时类型 ps:多态定义:把子类对象直接赋给父类的引用时,当运行时调用该引用类型的方法时,其方法行为总是表现出子类的行为特征,而不是父类的行 ...
- 编译时异常和运行时异常区别
文章目录 1.编译时异常因为什么而得名 2.编译时异常和运行时异常区别 3.编译时异常还有其他名字 4.运行时异常还有其他名字 5.所有异常都发生在运行阶段的 1.编译时异常因为什么而得名 编译时异常 ...
- C++编译时多态和运行时多态
C++编译时多态和运行时多态 作者:melonstreet 出处:https://www.cnblogs.com/QG-whz/p/5132745.html 本文版权归作者和博客园共有,欢迎转载,但未 ...
- 编译时异常和运行时异常的区别
编译时异常和运行时异常的区别 参考文章: (1)编译时异常和运行时异常的区别 (2)https://www.cnblogs.com/lxl57610/p/6716252.html (3)https:/ ...
- java编译时多态和运行时多态_运行时多态、编译时多态和重载、重写的关系(不区分Java和C#,保证能看懂!)...
以前在大学学习OOP的时候,知道了重载和重写的区别,但如果要把他们和多态联系起来,我想很多新手朋友和我当初一样是死记的,可是时间长了,自然而然就忘记了,最近在写测试的时候,终于"开窍&quo ...
- java 语法错误_java菜鸟提问:编译时异常和语法错误的区别?
语法错误是你真写错了,比如"All the people here work hardly."这句话就是语法错误,hard也可用作副词,所以"All the people ...
最新文章
- 应届毕业生没有工作经验,怎么才能找到合适的工作?
- redis详解(四)-- 高可用分布式集群
- [zz]c++ list sort方法
- 所以Apache基金会不受美国法律约束?
- CentOS 7 yum 安装php5.6
- C#单元测试如何查看输出的调试信息?
- 安卓学习笔记20:Fragment入门
- 安兔兔2月Android手机性价比榜出炉:Redmi包揽前三
- android 钢琴识别音阶对错_钢琴为什么会成为“乐器之王”
- 【书籍推荐】《美国黒室》
- BGSOUND与EMBED的区别
- Oracle GoldenGate 之 Director 监控工具安装和邮箱报警
- Xshell注册激活教程
- xshell查看hdfs文件目录路径_hdfs的shell操作
- 齐齐哈尔市全国计算机等级考试,2021年9月黑龙江省齐齐哈尔市全国计算机等级考试报名时间...
- Python 调用 ImageMagick 将常规图片转成 .ico 图片
- Broadcast Receiver(一)
- html5如何快速选择工具,PS抠图教程!教你PHOTOSHOP中5个快速选择工具
- 手写数字的分割和识别
- 杨米尔斯理论讲了什么
热门文章
- 微信重磅功能更新!加好友按人数收费,视频号付费订阅、微信版“知乎”来了...
- 将来有机会把自己的院子建成这种
- 计算机左侧没有桌面菜单栏,AI软件左侧的工具栏不见了没有了怎么显示出来
- 硬盘、光驱、刻录机维修技术
- 如何提高电商广告投放的转化率?
- Numpy 数组切片
- 筑龙网下载的文件格式是php_建筑工程竣工验收资料填报指南(范本)
- ios html调起高德地图,iOS 调用百度地图, 高德地图,苹果自带的地图
- Spark SQL操作多数据源
- 如何在Ubuntu上方便使用OpenAI API key