¿Por qué Java no hace inferencia de tipos?

43

Siempre me he preguntado por qué Java no hace inferencia de tipos dado que el lenguaje es el que es y su VM es muy madura. Google's Go es un ejemplo de un lenguaje con excelente inferencia de tipos y reduce la cantidad de escritura que uno tiene que hacer. ¿Hay alguna razón especial detrás de que esta característica no sea parte de Java?

    
pregunta cobie 19.01.2013 - 00:36

5 respuestas

59

Técnicamente hablando, Java tiene inferencias de tipo cuando se usan genéricos. Con un método genérico como

public <T> T foo(T t) {
  return t;
}

El compilador analizará y entenderá que cuando escribas

// String
foo("bar");
// Integer
foo(new Integer(42));

Se devolverá una cadena para la primera llamada y un entero para la segunda llamada en función de lo que se ingresó como argumento. Obtendrás la correcta verificación en tiempo de compilación como resultado. Además, en Java 7, se puede obtener una inferencia de tipo adicional cuando crear instancias genéricas como tal

Map<String, String> foo = new HashMap<>();

Java es lo suficientemente amable para completar los corchetes de ángulo en blanco para nosotros. Ahora, ¿por qué Java no admite inferencia de tipo como parte de la asignación de variables? En un momento dado, había un RFE para hacer inferencias de tipo en declaraciones de variables, pero esto se cerró como "No arreglaré" porque

  

Los seres humanos se benefician de la redundancia de la declaración de tipo de dos maneras.   Primero, el tipo redundante sirve como documentación valiosa, los lectores sí   no tiene que buscar la declaración de getMap () para averiguar qué tipo   vuelve.   Segundo, la redundancia permite al programador declarar el tipo deseado,   y, por lo tanto, beneficiarse de una verificación cruzada realizada por el compilador.

El colaborador que cerró esto también notó que simplemente se siente "un-java-like", con lo cual estoy de acuerdo. La verbosidad de Java puede ser tanto una bendición como una maldición, pero hace que el lenguaje sea lo que es.

Por supuesto, esa RFE en particular no fue el final de esa conversación. Durante Java 7, esta función fue nuevamente considerada , con algunas implementaciones de prueba siendo creado, incluyendo uno por el mismo James Gosling. Una vez más, esta función fue finalmente derribada.

Con el lanzamiento de Java 8, ahora obtenemos la inferencia de tipos como parte de lambdas como tal:

List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));

El compilador de Java puede ver el método Collections#sort(List<T>, Comparator<? super T>) y luego la interfaz de Comparator#compare(T o1, T o2) y determine que first y second deben ser String , lo que le permite al programador renunciar a tener que volver a escribir el tipo en la expresión lambda.

    
respondido por el Glenn Nelson 19.01.2013 - 04:51
15

Bueno, primero que nada, la inferencia de tipo no tiene nada que ver con la madurez del tiempo de ejecución, ya sea que el tiempo de ejecución sea una CPU de 30 años o una VM que sea tan nueva que los bits aún sean brillantes. todo se trata del compilador.

Dicho esto, está permitido para los genéricos, la razón por la que no está permitido para los tipos no genéricos parece ser debido a la filosofía, no hay nada que impida que los diseñadores lo agreguen.

Actualización: parece que Java 10 lo admite —- enlace

    
respondido por el jmoreno 19.01.2013 - 05:45
5

Por lo que sé, cuando Java fue diseñado a principios de los años noventa, la inferencia de tipo no era tan popular entre los lenguajes principales (pero ya era un concepto muy conocido, por ejemplo, en ML). Por lo tanto, puedo imaginar que la inferencia de tipos probablemente no se admitió porque Java estaba dirigida a programadores de C ++, Pascal u otros lenguajes principales que no la tenían (principio de la menor sorpresa).

Además, uno de los principios de diseño de Java es escribir cosas explícitamente para asegurarse de que el programador y el compilador tengan el mismo entendimiento del código: la información duplicada reduce las posibilidades de errores. Por supuesto, puede ser una cuestión de gusto si escribir unos cuantos caracteres más vale la seguridad adicional que proporciona, pero esta fue la filosofía de diseño seguida para Java: escribir cosas explícitamente.

No sé si Java obtendrá inferencia de tipo en el futuro, pero IMO sería una gran revolución para el lenguaje (como mencionó Glenn Nelson, se describió como "un-java-like") y luego uno también podría Considere eliminar el nombre de Java a favor de un nuevo nombre.

Si desea utilizar un lenguaje JVM con inferencia de tipo, puede usar Scala.

    
respondido por el Giorgio 19.01.2013 - 11:54
2

Puedo pensar en algunas posibles razones. Una es que la tipificación explícita es la autodocumentación. Java generalmente hace que esto sea una prioridad sobre la concisión. Otra razón podría ser en los casos en que el tipo es algo ambiguo. Como cuando un tipo o cualquier subtipo puede satisfacer una rutina. Supongamos que desea utilizar una Lista, pero alguien aparece y utiliza un método exclusivo de ArrayList. El JIT inferiría un ArrayList y continuaría incluso si quisiera un error de compilación.

    
respondido por el jiggy 19.01.2013 - 04:56
0

Se contradice con la recomendación bien establecida de declarar variables utilizando la interfaz más genérica que se ajuste a sus necesidades e inicializarlas con una clase de implementación apropiada, como en

Collection<String> names = new ArrayList<>();

Efectivamente,

var names = new ArrayList<String>();

no es más que azúcar sintáctico para

ArrayList<String> names = new ArrayList<String>();

Si lo desea, su IDE puede producirlo a partir de la expresión new ArrayList<String>() con "un clic" (refactorizar / crear variable local), pero recuerde que contradice la recomendación de "usar interfaces".

    
respondido por el Ralf Kleberhoff 23.09.2018 - 21:27

Lea otras preguntas en las etiquetas

Comentarios Recientes

Muchos tipos estáticos de recursos en Java se compilan en tipo Java en lugar de inferencia de tipos. La inferencia de tipos es realmente solo un tipo que puede realizar durante la ejecución de su código y solo leer o escribir información de tipo que escriba. Para verificar que no se extrajo de su programa, no solo debe abrir en la herramienta de depuración completa y abrir una lista de opciones como fuentes de clase en Visual Studio. Simplemente termine de registrar cada tipo, referencia y tiempo de compilación... Lee mas