翻译人员: 铁锚

翻译时间: 2013年11月13日

原文链接: How does Java handle aliasing?

什么是Java的引用别名机制

Java的引用别名机制(原文为Aliasing,别名,即Java中的多态)意味着多个引用变量可以定位到同一个实际物理对象,而这些引用变量可以是不同的类型.

下面的代码中,S类继承P类, pp 和 ss 分别是P类型 和 S类型的两个数组变量名.

public class TestPolyMorphism {
    public static class P{
    public void print(String message){
        System.out.println("P-->"+message);
    }
    }
    public static class S extends P{
    public void print(String message){
        System.out.println("S-->"+message);
    }
    }
    public static void main(String[] args) {
    S[] ss = new S[10];
    P[] pp = ss;
    ss[0] = new S();
    pp[0].print("你好");
    // !!运行时错误,不能将父类对象,赋给子类数组;
    //pp[1] = new P();//java.lang.ArrayStoreException
    }
}

在内存中,pp和ss都指向了同样的内存地址.(我们可以说,指针pp,指针ss;或者说pp引用,ss引用.)

图1

pp和ss指向了同一个物理地址,在实际运行过程中,多态特性根据真实的对象类型决定调用父类还是子类的具体方法,而不是根据引用变量的类型.



Java 如何处理引用别名机制

如果将下列代码拷贝到eclipse中,将不会有什么编译期错误:

package think;

public class TestPolyMorphism {
    public static class P{
    public void print(String message){
        System.out.println("P-->"+message);
    }
    }
    public static class S extends P{
    public void print(String message){
        System.out.println("S-->"+message);
    }
    public void paint(String message){
        System.out.println("S-->执行一些绘画操作-->"+message);
    }
    }
    public static void main(String[] args) {
    S[] arr = new S[10];
    P[] pp = arr;
    arr[0] = new S();
    pp[0].print("你好");
    pp[1] = new P(); // !!运行时错误,不能将父类对象,赋给子类数组;java.lang.ArrayStoreException
    }
}

但在运行期将会显示如下错误:

Exception in thread "main" java.lang.ArrayStoreException: think.TestPolyMorphism$P
    at think.TestPolyMorphism.main(TestPolyMorphism.java:22)

原因是Java在运行时才处理别名引用,在程序运行过程中,虚拟机发现 数组pp的第一个元素是 SS类型的对象,而不是PP类型的。

因此,只有修改为正确的代码,才可以正常运行:

S[] arr = new S[10];
P[] pp = arr;
pp[1] = new S();
pp[1].print("你好");

输出没有错误:

S-->你好

相关文章:

1. Linux Process Programming – fork()

2. 图说Java —— 理解Java机制最受欢迎的8幅图

3. Why do we need Generic Types in Java?

4. Overriding and overloading in Java with examples

Java对象引用处理机制的更多相关文章

  1. 「轉」Java的内存机制

    0.参考资料: http://www.j2megame.org/index.php/content/view/2246/125.html 1.Java的内存机制 Java 把内存划分成两种:一种是栈内 ...

  2. Java GC回收机制

    优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...

  3. 成为JavaGC专家(1)—深入浅出Java垃圾回收机制

    转载自:http://www.importnew.com/1993.html 对于Java开发人员来说,了解垃圾回收机制(GC)有哪些好处呢?首先可以满足作为一名软件工程师的求知欲,其次,深入了解GC ...

  4. Java内存回收机制

    在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险.但是,也正 ...

  5. Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别

    一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:   其中

  6. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  7. [转]Java 动态代理机制分析及扩展

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  8. java 垃圾回收机制 引用类型

    Java语言的一个重要特性是引入了自动的内存管理机制,使得开发人员不用自己来管理应用中的内存.C/C++开发人员需要通过malloc/free 和new/delete等函数来显式的分配和释放内存.这对 ...

  9. 转:成为JavaGC专家Part I — 深入浅出Java垃圾回收机制

    文章来自于:http://www.importnew.com/1993.html 对于Java开发人员来说,了解垃圾回收机制(GC)有哪些好处呢?首先可以满足作为一名软件工程师的求知欲,其次,深入了解 ...

随机推荐

  1. 【图文详解】Hadoop集群搭建(CentOs6.3)

    本文主要详细地描述了hadoop集群的搭建以及一些配置文件的说明,用于自己复习以及供新人学习,若有错误之处还请指出. 前期准备 先给出我的集群架构: 到hadoop官网下载好hadoop安装包http ...

  2. java中的final和volatile详解

    相比synchronized,final和volatile也是经常使用的关键字,下面聊一聊这两个关键字的使用和实现 1.使用 final使用: 修饰类表示该类为终态类,无法被继承 修饰方法表示该方法无 ...

  3. 安卓开发遇到Error:Execution failed for task ':app:transformClassesWithDexForDebug'.

    问题如下: Error:Execution failed for task ':app:transformClassesWithDexForDebug'. com.android.build.api. ...

  4. SQL实例整理

    本文适合将w3school的SQL教程(http://www.w3school.com.cn/sql/sql_create_table.asp)都基本看过一遍的猿友阅读. 说说博主的情况吧.毕业找工作 ...

  5. Java面向对象要点

    面向对象: 一.基本概念     类与对象的基本概念:         1.void类型是不需要返回值的,其他类型全部都需要返回值.             public  void  tell(){ ...

  6. Scala:数组

    http://blog.csdn.net/pipisorry/article/details/52902432 ) 或var z = new Array[String](3) 以上语法中,z 声明一个 ...

  7. PHP和MySQL Web开发学习笔记介绍

    前言 从2016年2月1日开始,之后的几个月左右的时间里,我会写一个系列的PHP和MySQL Web开发的学习笔记.我之前一直从事Java语言的开发工作,最近这段时间非常想学习一门语言,就选择了PHP ...

  8. EBS业务学习之应付INVOICE类型

    INVOICE类型 类      型 描           述 标准INVOICE 是指由于采购货物或接受劳务,从供应商处取得的INVOICE (标准INVOICE,既可以和订单匹配,也可以不匹配) ...

  9. Android Studio基本配置

    主题设置 File→Settings- 添加第三方主题 网址:http://www.ideacolorthemes.org/home/ File→Import Settings- 设置控制台字体大小 ...

  10. FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...