关于Java 7 API中FileInputStream的两个重载构造函数的有趣之处

2022-09-02 01:17:09

在谈论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 的可接受候选项,因此编译器无法决定选择哪种方法。

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

  1. public FileInputStream(String name) throws FileNotFoundException {.....}
  2. public FileInputStream(File file) throws 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,但这是一个单独的问题,稍后会出现。在此之前,如何解决歧义?


答案 1

您的错误在这里:

现在,如果“name”确实为 null,则计算结果又等同于调用this(name != null ? new File(name) : null);this(null);FileInputStream(null);

它实际上的计算结果为 -- 即显式键入为 的 null 值。这是因为表达式必须具有类型,而该类型是两个选项中最具体的类型。在本例中,一个备选项的类型为 as,另一个替代项的类型为 ,因此最具体的常见类型是 。this((File) null)Filename != null ? new File(name) : nullFilenullFile

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

File file = null;
new FileInputStream(file);

答案 2

条件运算符的结果的类型为 。JLS 定义了:File

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

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


推荐