java – 使用超级/子类型重载的方法/构造函数
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 使用超级/子类型重载的方法/构造函数,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3394字,纯文字阅读大概需要5分钟。
内容图文
![java – 使用超级/子类型重载的方法/构造函数](/upload/InfoBanner/zyjiaocheng/747/768fcf5d3e4742ef81300331ace1f2af.jpg)
关于在某些情况下调用哪个重载方法,我有一些问题.
情况1:
public void someMethod(Object obj){
System.out.println("Object");
}
public void someMethod(InputStream is){
System.out.println("InputStream");
}
public void someMethod(FilterInputStream fis){
System.out.println("FilterInputStream");
}
我知道,如果我传递一个字符串,它将打印“对象”.但是,如果我传递一个InputStream怎么办?如果我传递一些像BufferedInputStream这样的东西会让人感到困惑.这会调用Object one,InputStream one还是FilterInputStream?方法的顺序是否重要?
案例2:
这有点棘手,因为它利用了多个接口继承. BlockingQueue和Deque都不是彼此的子/超类型,但两者都是BlockingDeque的超类型. Sun通过接口添加了多重继承,因为它们不需要树结构. BlockingDeque的声明是
公共接口BlockingDeque扩展了BlockingQueue,Deque {.
public void someMethod(BlockingQueue bq){
System.out.println("BlockingQueue");
}
public void someMethod(Deque bq){
System.out.println("Deque");
}
public void someCaller(){
BlockingDeque bd = new LinkedBlockingDeque();
someMethod(bd);
}
这会调用someMethod(BlockingQueue)还是someMethod(Deque)?
案例3:
你可以把这两个结合起来:
public void someMethod(Queue q){
//...
}
public void someMethod(Deque q){
//...
}
public void someMethod(List p){
//...
}
public void someCaller(){
someMethod(new LinkedList());
}
同样的问题:someMethod(Queue),someMethod(Deque)或someMethod(List)?
案例4:
通过引入两个参数,你也可以使事情变得非常复杂:
public void someMethod(Collection c1, List c2){
//...
}
public void someMethod(List c1, Collection c2){
//...
}
public void someCaller(){
someMethod(new ArrayList(), new ArrayList());
}
这会调用someMethod(Collection,List),反之亦然?
案例5:
当它们有不同的返回类型时会变得更糟:
public Class<?> someMethod(BlockingQueue bq){
return BlockingQueue.class;
}
public String someMethod(Deque bq){
return "Deque";
}
public void someCaller(){
BlockingDeque bd = new LinkedBlockingDeque();
System.out.println(someMethod(bd));
}
这些可能会非常糟糕.在这种情况下,someCaller会打印什么? someMethod(BlockingQueue).toString()或someMethod(Deque)?
解决方法:
一般来说,Java会调用最窄的非模糊定义,因此对于前几种情况,如果传递一个窄类型,它将调用最窄的函数,如果你传递一个更宽的类型(比如InputStream),你会获得更宽泛的类型的函数(在用于InputStream的case 1,即方法2). Here’s a simple test和note that downcasting will widen the type, and call the wider type’s method.
核心问题是Java是否可以解析一个独特的调用函数.因此,这意味着如果您提供具有多个匹配项的定义,则需要匹配最高已知类型,或者唯一匹配更宽泛的类型,而不匹配更高类型.基本上:如果匹配多个函数,其中一个函数需要在层次结构中更高,以便Java解决差异,否则调用约定肯定是模糊的.
当方法签名不明确时,Java似乎会抛出编译错误.在我看来,案例4在规范上是最糟糕的例子,所以我写了一个quick test并确实得到了预期的编译错误,抱怨函数调用的模糊匹配.
案例5没有做任何更好或更糟的事情:Java不使用返回类型来消除调用哪个方法的歧义,因此它不会帮助你 – 因为定义已经含糊不清,你仍然会最终得到编译错误.
所以快速总结:
>使用普通InputStream调用时由于模糊调用导致的编译错误,使用FilteredInputStream调用使用3rd def,调用实现InputStream但不是FilteredInputStream的东西使用2nd def,其他任何东西,1st def
>第二次定义
>含糊不清,会导致编译错误
>含糊不清,会导致编译错误
>含糊不清,会导致编译错误
最后,如果您怀疑自己正在调用您认为应该是的定义,那么您应该考虑更改代码以消除歧义,或者指定正确的类型参数来调用“正确”函数. Java会告诉你什么时候它不能做出明智的决定(当事情真的很模糊时),但避免任何这些问题的最好方法是通过一致和明确的实现.不要做奇怪的事情,比如案例4,你不会遇到奇怪的问题.
内容总结
以上是互联网集市为您收集整理的java – 使用超级/子类型重载的方法/构造函数全部内容,希望文章能够帮你解决java – 使用超级/子类型重载的方法/构造函数所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。