调用重载方法时出现的问题

问题描述

publicclassTest{publicstaticvoidmain(String[]args){Testa=newTest();a.test(null);}publicvoidtest(into){System.out.println("test1...int");}publicvoidtest(Stringo){System.out.println("test2...String");}publicvoidtest(Objecto){System.out.println("test3...Object");}}

为什么会输出‘test2...String’???

解决方案

解决方案二:
因为会往最窄的范围靠,null同时满足String和Object,但String比Object窄《java解惑》一书有详细说明
解决方案三:
引用1楼ticmy的回复:

因为会往最窄的范围靠,null同时满足String和Object,但String比Object窄《java解惑》一书有详细说明

能说具体一些,或者把这本书的解释粘过来可以吗
解决方案四:
谜题46:令人混淆的构造器案例本谜题呈现给你了两个容易令人混淆的构造器。main方法调用了一个构造器,但是它调用的到底是哪一个呢?该程序的输出取决于这个问题的答案。那么它到底会打印出什么呢?甚至它是否是合法的呢?publicclassConfusing{privateConfusing(Objecto){System.out.println("Object");}privateConfusing(double[]dArray){System.out.println("doublearray");}publicstaticvoidmain(String[]args){newConfusing(null);}}传递给构造器的参数是一个空的对象引用,因此,初看起来,该程序好像应该调用参数类型为Object的重载版本,并且将打印出Object。另一方面,数组也是引用类型,因此null也可以应用于类型为double[]的重载版本。你由此可能会得出结论:这个调用是模棱两可的,该程序应该不能编译。如果你试着去运行该程序,就会发现这些直观感觉都是不对的:该程序打印的是doublearray。这种行为可能显得有悖常理,但是有一个很好的理由可以解释它。Java的重载解析过程是以两阶段运行的。第一阶段选取所有可获得并且可应用的方法或构造器。第二阶段在第一阶段选取的方法或构造器中选取最精确的一个。如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性[JLS15.12.2.5]。在我们的程序中,两个构造器都是可获得并且可应用的。构造器Confusing(Object)可以接受任何传递给Confusing(double[])的参数,因此Confusing(Object)相对缺乏精确性。(每一个double数组都是一个Object,但是每一个Object并不一定是一个double数组。)因此,最精确的构造器就是Confusing(double[]),这也就解释了为什么程序会产生这样的输出。如果你传递的是一个double[]类型的值,那么这种行为是有意义的;但是如果你传递的是null,这种行为就有违直觉了。理解本谜题的关键在于在测试哪一个方法或构造器最精确时,这些测试没有使用实际的参数:即出现在调用中的参数。这些参数只是被用来确定哪一个重载版本是可应用的。一旦编译器确定了哪些重载版本是可获得且可应用的,它就会选择最精确的一个重载版本,而此时使用的仅仅是形式参数:即出现在声明中的参数。要想用一个null参数来调用Confusing(Object)构造器,你需要这样写代码:newConfusing((Object)null)。这可以确保只有Confusing(Object)是可应用的。更一般地讲,要想强制要求编译器选择一个精确的重载版本,需要将实际的参数转型为形式参数所声明的类型。以这种方式来在多个重载版本中进行选择是相当令人不快的。在你的API中,应该确保不会让客户端走这种极端。理想状态下,你应该避免使用重载:为不同的方法取不同的名称。当然,有时候这无法实现,例如,构造器就没有名称,因而也就无法被赋予不同的名称。然而,你可以通过将构造器设置为私有的并提供公有的静态工厂,以此来缓解这个问题[EJItem1]。如果构造器有许多参数,你可以用Builder模式[Gamma95]来减少对重载版本的需求量。如果你确实进行了重载,那么请确保所有的重载版本所接受的参数类型都互不兼容,这样,任何两个重载版本都不会同时是可应用的。如果做不到这一点,那么就请确保所有可应用的重载版本都具有相同的行为[EJItem26]。总之,重载版本的解析可能会产生混淆。应该尽可能地避免重载,如果你必须进行重载,那么你必须遵守上述方针,以最小化这种混淆。如果一个设计糟糕的API强制你在不同的重载版本之间进行选择,那么请将实际的参数转型为你希望调用的重载版本的形式参数所具有的类型。

时间: 2024-10-23 10:41:52

调用重载方法时出现的问题的相关文章

window location-window.location调用java方法时出现 The requested resource is not available.

问题描述 window.location调用java方法时出现 The requested resource is not available. JSP代码 <%@ page language="java" import="jikon.action.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = requ

java-文本域ta 调用settext方法时提示出错

问题描述 文本域ta 调用settext方法时提示出错 向文本域中输入文字时,系统提示:语法错误在令牌s,构造错误在s.语句如下: JTextArea ta = new JTextArea(20,30); ta.setText(" "); 请路过的大神帮帮忙,谢谢 解决方案 光 这两句代码怎么看出错误.....

c#-调用AddRange()方法时被提示&amp;amp;quot;集合被修改,枚举操作可能无法进行&amp;amp;quot;

问题描述 调用AddRange()方法时被提示"集合被修改,枚举操作可能无法进行" 实在搞不懂来提问,我并没有修改什么东西啊. 解决方案 看你的代码,addrange本身会修改集合.不要在foreach迭代中调用它. 解决方案二: 循环和迭代中不要对集合进行修改

webBrowser 调用 Refresh 方法时不会发生 DocumentCompleted 事件?

问题描述 webBrowser调用Refresh方法时不会发生DocumentCompleted事件有没有很么方法可以解决下吗? 解决方案 解决方案二:没有人知道吗解决方案三:文档刷新只重新加载当前页,因此在调用Refresh方法时不会发生Navigating.Navigated和DocumentCompleted事件.

Jquery调用webService方法 时

问题描述 触发控件没反应下面是代码-------------------------------------------------------------------<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default"%><!DOCTYPEhtml><htmlxmlns=&q

浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题_jquery

今天用firefox调试一个用jquery里面的封装的方法与后台交互的时候,firefox死活不弹窗. 而之前用谷歌浏览器顺利通过.之后发现各自浏览器对浏览器默认值的处理是不一样的.总结: 如果返回的是json,应该带上该参数,返回的是text也一样. $.post(url,param,function(data),param);//最后一个参数param对应返回信息的类型,一般要带上,避免 因不同浏览器默认设置的不同造成的问题.

java中在调用一个方法时,堆和栈是如何分配的?

问题描述 如题.java一个类中方法太多,会有什么负面影响? 解决方案 解决方案二:看<深入Java虚拟机>第二版第五章解决方案三:一个类中方法过多,会造成系统分层困难,耦合度会比较大!~解决方案四:还没有那么深入,帮顶.祝楼主好运

运算符重载方法,扩展方法,以及方法参数

运算符重载方法 一 些编程语言允许定义运算符如果操作类型的实例,例如System.String,System.Decimal,和System.DateTime,它们 重载了==和!=运算符.但是对于CLR来说,它是完全不知道像"=="和"!="这些运算符是干什么的.编程语言定义了每一种运算符的意义以及当这些运 算符的符号出现时应该生成什么样的代码.例如C#里面,数值类型的当遇到"+"这个符号时,在编译时会生成将两个number加起来的代码,如果是

arraylist-JAVA小白问题:测试Iterable接口的Iterator迭代器方法时遇到的疑问

问题描述 JAVA小白问题:测试Iterable接口的Iterator迭代器方法时遇到的疑问 创建个Arraylist集合,放几个数据,然后用迭代器循环遍历,同时想做个判断,如果等于指定的数值的数据出现了,就删除它,继续迭代别的元素,单独用remove删除方法没问题,但把它和next方法合起来用,就报错了,求解,谢谢! 解决方案 既然你自己也标注了正确的和错误的,我给你提一下,你这里有三个点: 分别是,it.hasnext(),第一个it.next(),第二个next. 先解释一下it.hasn