22

在谈论 FileInputStream 之前,我先从一个场景开始,其中有两个完全有效的重载方法,但编译器会感到困惑,然后在响应某些输入时报告编译时错误。

以下是方法。

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

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

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

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);  
  }  
}  

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

当我带着上面的概念,深入研究 Java 7 API 到 FileInputStream 类并研究该类的两个重载构造函数时,这就是我感到困惑的地方。

  1. 公共文件输入流(字符串名称)抛出 FileNotFoundException {.....}
  2. 公共 FileInputStream(文件文件)抛出 FileNotFoundException {.....}

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

public FileInputStream(String name) throws FileNotFoundException {  
       this(name != null ? new File(name) : null);  
} 

现在,如果“ name ”确实为空,则 this(name != null ? new File(name) : null); 评估为this(null); 这又相当于调用FileInputStream(null); 但随后FileInputStream(String)FileInputStream(File)都成为使用空值调用的可能选择。它不会引起歧义吗?那么,是否存在编译时错误?

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

4

2 回答 2

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);
于 2014-06-26T07:31:27.737 回答
15

条件运算符的结果类型是FileJLS定义:

如果第二个和第三个操作数之一是空类型,另一个是引用类型,那么条件表达式的类型就是那个引用类型。

所以应该调用哪个构造函数没有歧义

于 2014-06-26T07:23:59.373 回答