Подтвердить что ты не робот

Что-то интересное о двух перегруженных конструкторах FileInputStream в API Java 7

Прежде чем говорить о 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 literal может быть передано переменной double, оба метода являются приемлемыми кандидатами для литеральных значений 2 и 3, поэтому компилятор не может решить, какой метод выбрать.

Здесь я смущаюсь, когда беру на себя вышеуказанную концепцию, погружаюсь дальше в API Java 7 в класс FileInputStream и изучаю два перегруженных конструктора этого класса.

  • public FileInputStream (String name) выдает FileNotFoundException {.....}
  • public FileInputStream (файл файла) выдает FileNotFoundException {.....}

В соответствии с исходным кодом Java 7 API определение версии, которая принимает объект String в качестве аргумента:

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

Теперь, если " name" действительно имеет значение null, this (name!= null? new File (name): null); оценивает это ( null);, что в свою очередь эквивалентно вызову FileInputStream (null);, но затем оба FileInputStream (String) и FileInputStream (File) становятся возможными вариантами, вызываемыми с нулевым значением. Разве это не вызывает двусмысленности? Итак, не существует ли ошибки времени компиляции?

Я понимаю, что в конечном итоге возникает исключение FileNotFoundException, но это отдельная проблема, которая приходит позже. Как неоднозначность решена до этого?

4b9b3361

Ответ 1

Ваша ошибка:

Теперь, если "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);

Ответ 2

Тип результата условного оператора File. JLS определяет:

Если один из второго и третьего операндов имеет нулевой тип, а тип другого - ссылочный тип, то тип условного выражения является ссылочным типом.

Таким образом, нет никакой двусмысленности в отношении того, какой конструктор следует называть