metodo - Algo interesante sobre dos constructores sobrecargados de FileInputStream en Java 7 API
inputstream read file (2)
Antes de hablar sobre FileInputStream, estoy empezando con un escenario en el que hay dos métodos sobrecargados perfectamente válidos, pero el compilador se confunde y luego informa un error de tiempo de compilación en respuesta a ciertas entradas.
Aquí están los métodos.
double calcAverage(double marks1, int marks2) {
return (marks1 + marks2)/2.0;
}
double calcAverage(int marks1, double marks2) {
return (marks1 + marks2)/2.0;
}
Aquí está el código completo que muestra el uso de los métodos:
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);
}
}
Debido a que se puede pasar un valor literal int a una variable de tipo doble, ambos métodos son candidatos aceptables para los valores literales 2 y 3 , y por lo tanto el compilador no puede decidir qué método elegir.
Aquí es donde me confundo cuando llevo el concepto anterior conmigo, profundizo en la API de Java 7 a la clase FileInputStream y estudio sobre dos constructores sobrecargados de esa clase.
- FileInputStream público (nombre de cadena) lanza la excepción FileNotFoundException {.....}
- FileInputStream (archivo de archivo) público lanza la excepción FileNotFoundException {.....}
De acuerdo con el código fuente de la API de Java 7, la definición de la versión que toma un objeto String como argumento es:
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
Ahora, si " nombre " es de hecho nulo, este (nombre! = Nulo? Nuevo Archivo (nombre): nulo); evalúa a esto (nulo); que a su vez es equivalente a la invocación de FileInputStream (null); pero entonces tanto FileInputStream (String) como FileInputStream (File) se convierten en posibles opciones para ser invocadas con un valor nulo. ¿No da lugar a la ambigüedad? Entonces, ¿no hay un error de compilación para eso?
Entiendo que eventualmente se genera una excepción FileNotFoundException, pero es un problema aparte que viene más adelante. ¿Cómo se resuelve la ambigüedad antes de eso?
El tipo del resultado del operador condicional es File
. El JLS define:
Si uno de los operandos segundo y tercero es del tipo nulo y el tipo del otro es un tipo de referencia, entonces el tipo de la expresión condicional es ese tipo de referencia.
Así que no hay ambigüedad sobre qué constructor debería llamarse
Tu error está aquí:
Ahora, si "nombre" es de hecho nulo,
this(name != null ? new File(name) : null);
evalúa athis(null);
que a su vez es equivalente a la invocación deFileInputStream(null);
En realidad se evalúa a this((File) null)
, es decir, un valor nulo explícitamente escrito como File
. Esto es porque la expresión name != null ? new File(name) : null
name != null ? new File(name) : null
tiene que tener un tipo, y ese tipo es el tipo más específico de las dos alternativas. En este caso, una alternativa se escribe como File
y la otra se escribe como null
, por lo que el tipo común más específico es File
.
Es por eso que es capaz de resolverlo sin ambigüedades al constructor FileInputStream(File)
. Es análogo a:
File file = null;
new FileInputStream(file);