故事背景

  《狸猫换太子》在我国民间文学中很出名,故事剧情大致如下:北宋第三位皇帝宋真宗赵恒年长无子,他的两个妃子刘妃与李妃同时怀了身孕。真宗召见二人,各赐信物,并声明哪个生了儿子就立谁为皇后。生性阴险的刘妃在太监郭槐的帮助下,把李妃生下的孩子换成了剥了皮的狸猫,命承御寇珠将孩子抛人九曲桥下淹死。

寇珠不忍,求计于太监陈琳,将太子藏入妆盒,密送八贤王赵德芳处抚养。刘妃诬告李妃产下妖摩,于是真宗将李妃贬入冷宫,册封刘妃为皇后。郭槐告发寇珠与陈琳在九曲桥私会,刘皇后命陈琳拷问寇珠,寇珠不屈,触柱而亡。刘皇后又命郭槐火烧冷官,李妃被内监救出,流落民间。

18年后,真宗死,李妃之子赵祯即位为仁宗,包拯至陈州赈济,李妃鸣冤,包拯受状查明沉冤。仁宗斩郭槐,贬刘大后,迎母亲回官,母子团聚,“狸猫换太子”真相大自。

java之狸猫太子

我们假定正确的构造方法在java中为太子,假的构造方法为狸猫,那我们看一下下面的程序会打印出什么结果吧?

public class ConstructorTest {
static {
System.out.println("who is prince? ");
}
public void ConstructorTest() {
System.out.println("i am prince!");
}
public void getName() {
System.out.println("i am not prince");
}
public static void main(String[] args) {
ConstructorTest test=new ConstructorTest();
test.getName();
}
}

我们本来想打印出太子:

who is prince?
i am prince

真实运行打印出的却是狸猫:

who is prince?
i am not prince

那到底是什么一回事呢?

原来是皇帝受奸臣void 蒙蔽了,将真假太子弄错了。

太监void后面的不是太子(构造器),而是普通方法,在main方法中并没调用该方法,而由于没有任何声明的构造器,所以编译器会帮助(真的是在帮忙吗?)生成一个公共的无参数构造器,它除了初始化它所创建的域实例之外,不做任何事情。

java之太子之争

  因构造方法可以有多个,就会产生太子之争,那么怎么识别谁才是真正的太子呢?

public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
} private Confusing(double[] dArray) {
System.out.println("double array");
} public static void main(String[] args) {
new Confusing(null);
}
}

上面的题目给你了两个容易令人混淆的构造器。main 方法调用了一个构造器,但是它调用的到底是哪一个呢?该程序的输出取决于这个问题的答案。那么它到底会打印出什么呢?甚至它是否是合法的呢?

Java 的方法(包括构造器方法)触发过程是以两阶段运行的。第一阶段选取所有可获得并且可应用的方法或构造器。第二阶段在第一阶段选取的方法或构造器中选取最精确的一个。如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性[JLS 15.12.2.5]

在我们的程序中,两个构造器都是可获得并且可应用的。构造器Confusing(Object)可以接受任何传递给Confusing(double[ ])的参数,因此Confusing(Object)相对缺乏精确性。(每一个double 数组都是一个Object,但是每一个Object 并不一定是一个double 数组。)因此,最精确的构造器就是

Confusing(double[ ])。故结果是:double array

参考资料

【1】https://baijiahao.baidu.com/s?id=1613952761238601257&wfr=spider&for=pc

【2】https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.12

【3】java解惑

谁是狸猫谁是太子?--戏说java构造器的更多相关文章

  1. scjp考试准备 - 7 - Java构造器

    题目——如下代码的执行结果: class Hello{ String title; int value; public Hello(){ title += " World!"; } ...

  2. 戏说Java多线程

    戏说Java多线程. package com.cmp.chengfu.app.jdk6.desktop; import java.awt.Desktop; import java.io.File; i ...

  3. 【原】戏说Java

    戏说Java 本文只是个人闲余之际写的,查阅了些许资料,仅当娱乐.如有雷同,纯属巧合.   如果要学好一个东西,就应该要把他拟人化,当做一个你的好朋友,对他产生兴趣,那么你自然而然就会学习好他了.俗话 ...

  4. Java构造器浅析

    Java构造器 问题引出 1.先看一段简单创建对象的例子: public class constructTest { public static void main(String[] args) { ...

  5. JAVA构造器,重载与重写

    1. java构造器 构造器也叫构造方法(constructor), 用于对象初始化. 构造器是一个创建对象时被自动创建的特殊方法,目的是对象的初始化. 构造器 的名称与类的名称一致. JAVA通过n ...

  6. 浅谈Java构造器

    Java构造器 每个类都有构造方法.如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法. 在创建一个对象的时候,至少要调用一个构造方法.构造方法的名称必须与类同名,一个类可以 ...

  7. java构造器级简单内存分析

    java构造器的使用(基础篇) 构造方法也叫构造器,是创建对象时执行的特殊方法,一般用于初始化新对象的属性. 基本定义语法: 访问控制符 构造方法名([参数列表]){ 方法体 } 注:"访问 ...

  8. 2016年,谁是最受欢迎的 Java EE 服务器?

    [编者按]本文作者为性能监控工具 Plumbr 创始人 Nikita Salnikov-tarnovski,主要介绍2016年度最广为使用的 Java EE 容器及其排名变化情况.本文系国内 ITOM ...

  9. java构造器

    java的构造器不是方法,因为没有返回值. 构造器可以重载. 构造器的访问说明符: private:只有本类可以使用这个构造器. protected:这个类的子类和包中的类都可以使用此构造器. pub ...

随机推荐

  1. js 分享一个 时钟效果

    <style>        *{            margin: 0;            padding: 0;        }        #outLine{       ...

  2. Python之变量、常量以及注释

    Python之变量.常量以及注释 一.什么是变量 变量,是用于在内存中存放程序数据的容器,怎么理解呢? 计算机的最核心的功能j就是"计算",计算需要数据源,数据源存在在内存里,比如 ...

  3. .NETCore Docker实现容器化与私有镜像仓库管理

    一.Docker介绍 Docker是用Go语言编写基于Linux操作系统的一些特性开发的,其提供了操作系统级别的抽象,是一种容器管理技术,它隔离了应用程序对基础架构(操作系统等)的依赖.相较于虚拟机而 ...

  4. Windows上IDEA搭建最新Spark2.4.3源码调试的开发环境

    相信很多同学都想通过阅读一些框架的源码,来提高自己的代码能力,但往往在第一步,搭建环境的时候就碰了壁. 本篇就来介绍下如何在Windows下,将最新版的Spark2.4.3编译,并导入到IDEA编译器 ...

  5. C#数据结构_查找

    查找:静态查找和动态查找. 衡量查找算法的最主要的标准是平均查找长度(Average Search Length,简 称 ASL).平均查找长度是指在查找过程中进行的关键码比较次数的平均值. 顺序查找 ...

  6. 王某人从0开始学习lorawan的笔记_0

    最近老板想做lorawan的项目,交给我了,我也应承下来了,但是!!!我TM连lorawan是啥子我都不知道啊啊啊啊啊! 真希望我女朋友可以看穿我的倔强,给我1千万,让我专心当舔狗,等等,我的女朋友? ...

  7. .gitignore不起作用,过滤规则

    git 通过配置.gitignore文件忽略掉的文件或目录,在.gitignore文件中的每一行保存一个匹配的规则 # 此为注释 – 将被 Git 忽略 *.a :忽略所有 .a 结尾的文件 !lib ...

  8. 2020届京东秋招正式批一面记录-Java开发-2019.08.31

    京东一面总结 总共时间持续时间约40分钟 1.你用过集合类里面哪些是线程安全的,哪些是线程不安全的?分别举两个例子? 线程安全:HashTable以及ConcurrentHashMap 非线程安全:A ...

  9. Docker Machine的使用

    前面两篇文章(<Asp.Net Core 发布到 Docker(Linux Centos 虚拟机,使用Dockerfile)> <Docker Compose的使用>),简单介 ...

  10. Bluetooth(蓝牙)连接过程分析

    一 基本概念 蓝牙的连接过程是十分重要的,特别是做蓝牙的技术人员来说,这个是十分重要的.理它的流程,是一件必修课.虽然进入蓝牙行业很久了,以前没怎么系统化的做一些事情,趁此机会,就梳理一下这里面的内容 ...