Desventajas del desarrollo de Java
Creo que los 10 problemas principales con el lenguaje Java son:
1. Falta de cierre: creo que esto no necesita explicación. La programación funcional existe desde hace décadas, pero en los últimos años ha ganado cada vez más atención, principalmente debido a su capacidad natural para escribir programas paralelos. Estoy parcialmente de acuerdo con Joshua Bloch, quien enfatizó que la introducción de cierres en Java debe repensarse (la forma en que BGGA lo propuso es realmente mala), al menos la ausencia de cierres hace que sea imposible realizar cualquier programación funcional real en Java.
2. Faltan funciones de primera: Este problema está algo relacionado con el anterior, pero creo que es peor. En Java, la única forma de lograr un efecto similar es utilizar la famosa, fea y trágica clase interna anónima de método único, pero este parece ser un enfoque deficiente. Incluso en C#, se proporciona una mejor implementación a través del mecanismo de proxy.
3. Tipos primitivos: Si todo en Java fueran objetos, qué perfecto sería, pero no lo diseñan de esta manera. Por lo tanto, esto ha generado algunos problemas, como no poder colocar un int en una colección. Esto se resolvió en Java5 mediante la función de autoboxing (mencionada a continuación). También causa problemas al pasar por valor y pasar por referencia los datos de tipo nativo se pasan a los métodos por valor (copiar una copia y luego pasarla a la función), mientras que el objeto real se pasa (Anotación: en realidad se copia la dirección del objeto). Al pasar nuevamente, también se debe pasar por valor, pero debido a que se puede acceder al objeto a través de esta dirección de objeto dentro de la función, el efecto es similar a pasar por referencia).
4. Autoboxing y autounboxing: esta característica se introdujo en Java5 para resolver problemas causados por la existencia de tipos nativos. Permite la conversión silenciosa de tipos primitivos en objetos correspondientes, pero esto a menudo genera otros problemas. Por ejemplo, Integer puede ser nulo, pero int no, por lo que en este momento la JVM solo puede generar una NullPointerException que es difícil de depurar. Además, también puede dar lugar a otros comportamientos extraños. Como en el siguiente ejemplo, nos resulta difícil entender por qué la variable test es falsa:
Intger a = new Integer(1024);
Intger b = new Integer(1024);
prueba booleana = a < b || a == b || a > b;
5. Clasificación de clases: los genéricos son una característica interesante introducida en Java 5, pero para mantener la compatibilidad con versiones anteriores de Java, faltan algunas características importantes, especialmente la incapacidad de reflexionar sobre tipos genéricos en tiempo de ejecución. Por ejemplo, tiene un método que acepta un parámetro Lista. Si se pasa una Lista, no puede saber el tipo exacto del tipo genérico en tiempo de ejecución. Asimismo, no puede crear matrices genéricas. Esto significa que, aunque el siguiente código parezca natural, no se compilará:
List[] listOfStrings = new List[3];
6. Alcance inevitable Advertencias de tipo: ¿Alguna vez lo ha hecho? ¿Te encontraste atrapado en una advertencia de tipo que era imposible de eliminar? Si usas genéricos como yo, apuesto a que te habrás encontrado con esto. De hecho, fueron los síntomas de escala de este problema los que los llevaron a pensar que era necesario introducir una anotación específica (@SuppressWarnings("unchecked")) para manejar esta situación, y creo que la genérica probablemente debería diseñarse mejor.
7. No puedes pasar void a llamadas a métodos: tengo que admitir que este requisito de pasar void a métodos parece un poco extraño a primera vista.
Me gusta DSL. Cuando implemento una característica específica de mi biblioteca DSL (lambdaj), tengo que declarar un método con una firma como esta: void doSomething (parámetro de objeto). Aquí está el parámetro pasado para este método. de otra llamada a un método, su único propósito es registrar la llamada misma para que pueda ejecutarse más tarde. Lo que me sorprende es que incluso si el método println devuelve void, no parece haber una buena razón por la que no puedo escribir el código de esta manera:
doSomething(System.out.println( "test")) ;
8. No existe un mecanismo de proxy nativo: Proxy es un modelo muy efectivo y ampliamente utilizado, pero el mecanismo de proxy proporcionado por Java solo apunta a interfaces, no a clases específicas. Es por eso que tantos marcos convencionales, como Spring e Hibernate, adoptan bibliotecas como cblib que proporcionan este mecanismo. Además, dado que cglib se implementa mediante la creación de una subclase de la clase proxy en tiempo de ejecución, estos métodos tienen una limitación bien conocida: no pueden representar clases finales, como String.
9. Declaración pobre de Switch...case: Java estipula que switch...case solo puede seleccionar int y enum (comenzando con Java 5). En comparación con lenguajes más modernos como Scala, esto parece simplemente demasiado débil.
10. Excepción marcada: al igual que los tipos nativos, las excepciones marcadas se han convertido en una fuente de pecado en Java. Obliga a los programadores a hacer una de las siguientes dos cosas extremadamente malas y molestas: llenar su código con una gran cantidad de declaraciones try...catch que son terribles, ilegibles y propensas a errores, y la mayor importancia de hacerlo es simplemente Empaque las excepciones detectadas en excepciones de tiempo de ejecución y luego vuelva a lanzarlas o contamine su API con una gran cantidad de cláusulas de declaración de lanzamiento, lo que hace que la interfaz carezca de flexibilidad y extensibilidad.
El verdadero problema es que la única solución a los principales problemas que mencioné aquí es tomar una decisión dolorosa, definir un nuevo conjunto de especificaciones de lenguaje y abandonar la dirección de compatibilidad con versiones anteriores. Supongo que nunca harán eso, aunque estoy seguro de que no sería demasiado difícil escribir un programa que pudiera convertir automáticamente fuentes antiguas de Java para hacerlas compatibles con una hipotética nueva versión. Finalmente, es por eso que decidí comenzar a buscar un lenguaje mejor compatible con JVM.