- 浏览: 108961 次
- 性别:
- 来自: 大连
文章分类
- 全部博客 (159)
- 前端开发 (6)
- jsp (4)
- jquery (17)
- 配置文件 (2)
- Spring (10)
- java (34)
- hibernate (9)
- VC++ win32 application (6)
- C++ (6)
- MFC文件夹对话框 (1)
- C (4)
- MFC (1)
- C# (3)
- 两个路由器怎么连接 (1)
- Maven3 (3)
- Servlet (10)
- Struts2 (6)
- jdom (1)
- Struts1 (1)
- Spring MVC (2)
- Ant (5)
- SSH (6)
- oracle 10g (1)
- ibatis (3)
- JPA (3)
- EJB (2)
- XML知识 (3)
- javascript (2)
- android (1)
- FreeMarker (1)
- dwr (1)
- Ext (10)
- EXCEL (1)
最新评论
比如:
package com.bjsxt;
public class Test2 {
public void info(Object obj) {
System.out.println("obj");
}
public void info(String str) {
System.out.println("str");
}
/**
* @param args
*/
public static void main(String[] args) {
Test2 T2 = new Test2();
T2.info(null);
}
}打印出:str
解释(主要是重载函数调用时精确性的问题)
《java解惑》
谜题46:令人混淆的构造器案例
本谜题呈现给你了两个容易令人混淆的构造器。main方法调用了一个构造器,但是它调用的到底是哪一个呢?该程序的输出取决于这个问题的答案。那么它到底会打印出什么呢?甚至它是否是合法的呢?
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);
}
}
传 递给构造器的参数是一个空的对象引用,因此,初看起来,该程序好像应该调用参数类型为Object的重载版本,并且将打印出Object。另一方面,数组 也是引用类型,因此null也可以应用于类型为double[ ]的重载版本。你由此可能会得出结论:这个调用是模棱两可的,该程序应该不能编译。如果你试着去运行该程序,就会发现这些直观感觉都是不对的:该程序打印 的是double array。这种行为可能显得有悖常理,但是有一个很好的理由可以解释它。
Java的重载解析过程是以两阶段运行的。第一阶段 选取所有可获得并且可应用的方法或构造器。第二阶段在第一阶段选取的方法或构造器中选取最精确的一个。如果一个方法或构造器可以接受传递给另一个方法或构 造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性[JLS 15.12.2.5]。
在我们的程序中,两个构造器都是可获得 并且可应用的。构造器Confusing(Object)可以接受任何传递给Confusing(double[ ])的参数,因此Confusing(Object)相对缺乏精确性。(每一个double数组都是一个Object,但是每一个Object并不一定是 一个double数组。)因此,最精确的构造器就是Confusing(double[ ]),这也就解释了为什么程序会产生这样的输出。
如 果你传递的是一个double[ ]类型的值,那么这种行为是有意义的;但是如果你传递的是null,这种行为就有违直觉了。理解本谜题的关键在于在测试哪一个方法或构造器最精确时,这些 测试没有使用实际的参数:即出现在调用中的参数。这些参数只是被用来确定哪一个重载版本是可应用的。一旦编译器确定了哪些重载版本是可获得且可应用的,它 就会选择最精确的一个重载版本,而此时使用的仅仅是形式参数:即出现在声明中的参数。
要想用一个null参数来调用 Confusing(Object)构造器,你需要这样写代码:new Confusing((Object)null)。这可以确保只有Confusing(Object)是可应用的。更一般地讲,要想强制要求编译器选择一 个精确的重载版本,需要将实际的参数转型为形式参数所声明的类型。
以这种方式来在多个重载版本中进行选择是相当令人不快的。在你的API 中,应该确保不会让客户端走这种极端。理想状态下,你应该避免使用重载:为不同的方法取不同的名称。当然,有时候这无法实现,例如,构造器就没有名称,因 而也就无法被赋予不同的名称。然而,你可以通过将构造器设置为私有的并提供公有的静态工厂,以此来缓解这个问题[EJ Item 1]。如果构造器有许多参数,你可以用Builder模式[Gamma95]来减少对重载版本的需求量。
如果你确实进行了重载,那么请确保所有的重载版本所接受的参数类型都互不兼容,这样,任何两个重载版本都不会同时是可应用的。如果做不到这一点,那么就请确保所有可应用的重载版本都具有相同的行为[EJ Item 26]。
总之,重载版本的解析可能会产生混淆。应该尽可能地避免重载,如果你必须进行重载,那么你必须遵守上述方针,以最小化这种混淆。如果一个设计糟糕的API强制你在不同的重载版本之间进行选择,那么请将实际的参数转型为你希望调用的重载版本的形式参数所具有的类型。
package com.bjsxt;
public class Test2 {
public void info(Object obj) {
System.out.println("obj");
}
public void info(String str) {
System.out.println("str");
}
/**
* @param args
*/
public static void main(String[] args) {
Test2 T2 = new Test2();
T2.info(null);
}
}打印出:str
解释(主要是重载函数调用时精确性的问题)
《java解惑》
谜题46:令人混淆的构造器案例
本谜题呈现给你了两个容易令人混淆的构造器。main方法调用了一个构造器,但是它调用的到底是哪一个呢?该程序的输出取决于这个问题的答案。那么它到底会打印出什么呢?甚至它是否是合法的呢?
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);
}
}
传 递给构造器的参数是一个空的对象引用,因此,初看起来,该程序好像应该调用参数类型为Object的重载版本,并且将打印出Object。另一方面,数组 也是引用类型,因此null也可以应用于类型为double[ ]的重载版本。你由此可能会得出结论:这个调用是模棱两可的,该程序应该不能编译。如果你试着去运行该程序,就会发现这些直观感觉都是不对的:该程序打印 的是double array。这种行为可能显得有悖常理,但是有一个很好的理由可以解释它。
Java的重载解析过程是以两阶段运行的。第一阶段 选取所有可获得并且可应用的方法或构造器。第二阶段在第一阶段选取的方法或构造器中选取最精确的一个。如果一个方法或构造器可以接受传递给另一个方法或构 造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性[JLS 15.12.2.5]。
在我们的程序中,两个构造器都是可获得 并且可应用的。构造器Confusing(Object)可以接受任何传递给Confusing(double[ ])的参数,因此Confusing(Object)相对缺乏精确性。(每一个double数组都是一个Object,但是每一个Object并不一定是 一个double数组。)因此,最精确的构造器就是Confusing(double[ ]),这也就解释了为什么程序会产生这样的输出。
如 果你传递的是一个double[ ]类型的值,那么这种行为是有意义的;但是如果你传递的是null,这种行为就有违直觉了。理解本谜题的关键在于在测试哪一个方法或构造器最精确时,这些 测试没有使用实际的参数:即出现在调用中的参数。这些参数只是被用来确定哪一个重载版本是可应用的。一旦编译器确定了哪些重载版本是可获得且可应用的,它 就会选择最精确的一个重载版本,而此时使用的仅仅是形式参数:即出现在声明中的参数。
要想用一个null参数来调用 Confusing(Object)构造器,你需要这样写代码:new Confusing((Object)null)。这可以确保只有Confusing(Object)是可应用的。更一般地讲,要想强制要求编译器选择一 个精确的重载版本,需要将实际的参数转型为形式参数所声明的类型。
以这种方式来在多个重载版本中进行选择是相当令人不快的。在你的API 中,应该确保不会让客户端走这种极端。理想状态下,你应该避免使用重载:为不同的方法取不同的名称。当然,有时候这无法实现,例如,构造器就没有名称,因 而也就无法被赋予不同的名称。然而,你可以通过将构造器设置为私有的并提供公有的静态工厂,以此来缓解这个问题[EJ Item 1]。如果构造器有许多参数,你可以用Builder模式[Gamma95]来减少对重载版本的需求量。
如果你确实进行了重载,那么请确保所有的重载版本所接受的参数类型都互不兼容,这样,任何两个重载版本都不会同时是可应用的。如果做不到这一点,那么就请确保所有可应用的重载版本都具有相同的行为[EJ Item 26]。
总之,重载版本的解析可能会产生混淆。应该尽可能地避免重载,如果你必须进行重载,那么你必须遵守上述方针,以最小化这种混淆。如果一个设计糟糕的API强制你在不同的重载版本之间进行选择,那么请将实际的参数转型为你希望调用的重载版本的形式参数所具有的类型。
发表评论
-
java的日期操作类
2014-09-16 15:00 527package cn.mldn; import ja ... -
列表框 JList
2014-08-16 19:19 478package net.mindview.util; ... -
分页类
2014-02-23 15:05 501package com.yxq.model; pub ... -
java mail
2014-02-14 15:13 391package com.util.mail; /** ... -
Map输出方式一:Iterator输出Map
2014-02-12 11:49 876package com.mldn.map; impo ... -
Comparable
2014-02-11 20:16 380package org.lxh.demo13.setdem ... -
Foreach与迭代器
2014-02-11 17:45 514到目前为止,foreach语法主要用于数组,但是它也可以应 ... -
打印流
2014-02-07 20:10 439package com.bjsxt.print; i ... -
管道流
2014-02-07 17:23 439package com.bjsxt.buffer; ... -
Tramsform IO
2014-02-07 16:15 627package com.bjsxt.transform; ... -
Buffered IO
2014-02-07 15:02 572package com.bjsxt.buffer; ... -
字符流
2014-02-07 10:32 605package com.bjsxt.reader; ... -
字节流
2014-02-06 17:57 500package com.bjsxt.stream; ... -
RandomAccessFile类
2014-02-06 13:18 588使用RandomAccessFile类写入数据 impor ... -
排序啊啊啊啊
2013-09-18 10:32 446package cn.mldn; public cl ... -
java_匿名内部类
2013-04-10 15:26 953package com.bitsoft.inner; ... -
java_内部类
2013-04-10 14:05 784package com.diaodiao.inner; ... -
JAVA----- String方面的面试举例
2013-03-31 00:55 741[img] [/img] package com.t ... -
反射机制(2)
2013-03-20 20:39 705package com.bjsxt.demo; im ... -
反射机制
2013-03-17 22:19 468package org.dcl.demo; inte ...
相关推荐
根据题目提供的信息,这是一道涉及SQL查询技巧的微软数据库面试题。虽然题目中的SQL代码与题目描述不完全对应,但我们可以基于题目描述中的信息来分析这个问题并给出解答。 ### 题目背景 题目描述指出,有一个表,...
针对这道面试题,可能的问题方向包括: 1. **Ajax的基本工作原理**:解释Ajax是如何通过XMLHttpRequest对象实现异步通信的,涉及的步骤包括创建对象、打开连接、设置请求方法、发送请求、接收响应和处理数据。 2. ...
2. **玻璃杯问题**:这是一道空间想象和逻辑操作题。通过移动一个杯子,改变水的位置,达到目标状态,考验的是观察力和逻辑推理能力。 3. **决斗问题**:这是关于概率和策略选择的问题。小李存活率最高的原因是他的...
"C#面试题10套" 本资源摘要信息涵盖了C#面试题10套,涵盖了C#、.NET、面试题等知识点,详细解释了每一个问题和答案。 问题一: 密码问题,涉及到逻辑思维和规则应用。问题中给出了五个字母K、L、M、N、O,要求在...
2. **状态机与决策树**:第三题描述了一个涉及多个小球的状态变化问题,这可以被视为一个状态机或决策树的问题,其中每个小球的选择都会导致不同的状态转移,最终目标是找到最优策略。这种思想在AI和游戏开发中极为...
根据给定的信息,我们可以推断出这是一道与算法相关的微软面试题目,主要涉及的是如何在1到100000的范围内寻找一个缺失的数字。从标题和描述来看,这个问题旨在测试应聘者的逻辑思维能力和解决问题的能力。下面将...
面试题20:树的遍历方式选择 树的遍历方式包括前序、中序、后序遍历,以及层次遍历,不同的遍历方式适用于不同的应用场景,如二叉查找树的查找操作常采用中序遍历。 #### 21. 面试题21:时间复杂度的选择 在算法...
在SQL Server中,面对这道面试题,我们需要编写T-SQL查询来满足以下需求:查询每个部门最后的人员变动时间,以及当前的人员数量、离职总人数和入职总人数。根据提供的表结构,我们可以推断出`DeptHistory`表包含了...
根据给定的信息,我们可以将这些经典的Google面试题分解为几个主要的知识点进行详细的解析: ### 1. 解密等式问题 **知识点:** - 数学逻辑与代数方程求解 - 字符串处理与算法设计 **解析:** 这道题目要求解一个...
"无领导小组讨论面试题资料.pdf" 本资源摘要信息主要关注无领导小组讨论面试题,涵盖了多个领域的知识点。下面是本资源摘要信息的详细解析: 试题一 试题一是一个典型的无领导小组讨论题。该试题考察了候选人的...
1. **[答案修正]精选微软数据结构+算法面试100题[V0.2版,前20题].pdf** - 这个文件包含了前20题的解答修正,可能涉及的问题有:二叉树的遍历、数组的旋转、字符串匹配、动态规划问题等。 2. **[最新答案V0.3版]...
【智力面试题】是面试中常见的一种考察方式,旨在测试应聘者的思维敏捷度、逻辑推理能力和创新解决问题的能力。以下是对几道经典的智力面试题的详细解答: 1. **5升和6升水壶取3升水问题**:这是一个典型的数学问题...
综上所述,通过遵循开发规范、优化数据结构和模型、使用合适的性能优化策略以及借助自动化工具,可以有效地解决面试题中提到的数据库性能和数据安全问题。同时,开发团队和DBA需要持续关注和改进这些方面,以确保...
从给定的文件信息来看,主要涉及的是IBM面试中出现的一些智力题,这些题目涵盖了逻辑推理、数学计算、策略思考等多个方面。下面将对部分题目进行详细的解析与知识点的提炼。 ### 题目解析 #### 1. 时间与速度问题 ...
根据提供的信息,我们可以总结出这份文档包含了从第41题到第60题的数据结构与算法面试题目。这些题目是从微软等知名公司的面试题目中精选出来的,并由原作者进行了整理和发布。以下是对这些题目的详细解读: ### 第...
这是一道典型的逻辑思维题,要求根据上排给出的十个数,在下排填出对应的十个数,使得下排每个数都是上排那十个数在下排出现的次数。 **解题思路**: 1. **初始化**:首先将所有数字初始化为0。 2. **逐个填充**:...
1. **华为一道排序题.mht** 排序算法是计算机科学的基础,华为可能在面试中考察应聘者对各种排序算法的理解和应用能力。这可能涉及到快速排序、归并排序、冒泡排序、插入排序、选择排序、堆排序等经典算法。例如,...
2016年的腾讯校招面试题主要分为问答题和选择题,旨在考察候选人的创新思维、逻辑推理、行业理解和实际操作能力。 一、问答题 1. 这道题目要求应聘者作为一名腾讯视频的节目制作人,设计一款互动型的真人秀节目。这...
这是一道典型的货币换算题。初始状态下可以用20元钱买到20瓶水,之后用空瓶兑换水。具体过程为:20瓶水→10瓶水(剩余10个空瓶)→5瓶水(剩余5个空瓶)→2瓶水(剩余1个空瓶)→1瓶水。最终总共可以喝20+10+5+2+1=...