关于Java 7 API中两个重载的FileInputStream构造函数的一些有趣内容

Moh*_*gar 22 java constructor-overloading

在讨论FileInputStream之前,我首先介绍了一个场景,其中有两个完全有效的重载方法,但编译器会感到困惑,然后报告编译时错误以响应某些输入.

这是方法.

double calcAverage(double marks1, int marks2) {  
   return (marks1 + marks2)/2.0;  
}  

double calcAverage(int marks1, double marks2) {  
   return (marks1 + marks2)/2.0;  
} 
Run Code Online (Sandbox Code Playgroud)

以下是显示方法用法的完整代码:

class MyClass {  
  double calcAverage(double marks1, int marks2) {  
            return (marks1 + marks2)/2.0;  
  }  
  double calcAverage(int marks1, double marks2) {  
           return (marks1 + marks2)/2.0;  
  }  
  public static void main(String args[]) {  
          MyClass myClass = new MyClass();  
          myClass.calcAverage(2, 3);  
  }  
}  
Run Code Online (Sandbox Code Playgroud)

因为int文字值可以传递给double类型的变量,所以这两个方法都是文字值23的可接受候选者,因此编译器无法决定选择哪个方法.

当我对我采用上述概念,进一步深入Java 7 API到FileInputStream类,并研究该类的两个重载构造函数时,我就会感到困惑.

  1. public FileInputStream(String name)抛出FileNotFoundException {.....}
  2. public FileInputStream(File file)抛出FileNotFoundException {.....}

根据Java 7 API源代码,以String对象作为参数的版本的定义是:

public FileInputStream(String name) throws FileNotFoundException {  
       this(name != null ? new File(name) : null);  
} 
Run Code Online (Sandbox Code Playgroud)

现在,如果" name "确实为null,那么(name!= null?new File(name):null); 评估为此(null); 而这相当于调用FileInputStream(null); 但随后FileInputStream(String)FileInputStream(File)都成为可以使用null值调用的选项.它不会引起歧义吗?那么,是不是存在编译时错误?

我确实理解最终会引发FileNotFoundException,但这是一个单独的问题.在此之前如何解决歧义?

ysh*_*vit 18

你的错误在这里:

现在,如果"name"确实为null,则this(name != null ? new File(name) : null);计算this(null);依次等于调用FileInputStream(null);

它实际上计算为this((File) null)- 即显式键入的空值File.这是因为表达式name != null ? new File(name) : null必须具有类型,并且该类型是两种备选方案中最具体的类型.在这种情况下,一个可替代的类型为File与其他的类型为null,所以最具体常见的类型是File.

这就是为什么它能够明确地将其解析为FileInputStream(File)构造函数.它类似于:

File file = null;
new FileInputStream(file);
Run Code Online (Sandbox Code Playgroud)

  • @MohammadAliAsgar重要的是要明白`?...:`bit不是语句的快捷方式,它是_expression_.所有表达式都有一个类型.例如,你不能使用`?`来调用返回`void`的方法. (4认同)

小智 15

条件运算符的结果类型是File.该JLS定义:

如果第二个和第三个操作数之一是null类型而另一个操作数的类型是引用类型,则条件表达式的类型是该引用类型.

因此,应该调用哪个构造函数没有歧义