La aparición de Kotlin es una ventaja importante para los desarrolladores. Un lenguaje de alto nivel que se integra perfectamente con Java expande enormemente las capacidades de los programadores. Sin embargo, en cualquier idioma constantemente encontramos algunos problemas que, por el contrario, crean restricciones, y Kotlin, por supuesto, no fue la excepción. Hablaremos de ellos hoy.

Kotlin estaba entusiasmado con la comunidad, ya que el nuevo lenguaje de programación simplifica enormemente la escritura de código, reemplazando a Java. Esto es especialmente notable en Android, donde aparecen nuevas versiones de Java, por decirlo suavemente, "con un crujido". Muchos dispositivos se actualizan con largos retrasos, incluso más: no reciben actualizaciones de firmware en absoluto. En el mejor de los casos, el soporte para el dispositivo finaliza aproximadamente 2 años después de su lanzamiento, lo que promete una, un máximo de dos actualizaciones del sistema. Sin embargo, las personas continúan usando dispositivos, lo que significa que los desarrolladores tienen que confiar tanto en el último (hasta ahora) Android 8 como en Android 5, o incluso versiones anteriores, donde ciertamente no solo existe la última, sino incluso la implementación actual de Java. Como referencia, ahora la cuota total de Android 7 y 8, esas versiones donde Java 8 es compatible con las bibliotecas del sistema, es del 42,9%, el resto es Java 7.
Algunos podrían decir que Java está en desuso. Pero también existe la opinión de que Java es un lenguaje que es bueno "tal cual" y no debe ser tocado. Es como un MCD (el mayor factor común) en matemáticas. Contiene un conjunto de funciones para caballeros, y para aquellos que necesitan funciones adicionales hoy en día, hay idiomas especiales disponibles que ya funcionan sobre la JVM. Muchos de estos lenguajes ya se han reproducido: Scala, Clojure, JRuby, Jython, Groovy y otros, menos conocidos. Sin embargo, Kotlin tiene una serie de ventajas. Este lenguaje le da más libertad al programador: le permite usar fragmentos preparados en Java al mismo tiempo, combinando código antiguo y nuevo.
Pero con todas las ventajas del nuevo lenguaje, que de ninguna manera discutimos, durante el proceso de desarrollo se encontraron algunas desventajas. Y hoy sería interesante escuchar la opinión de los colegas sobre si interfieren con el trabajo de la misma manera que nosotros.
No se puede ocultar el espectáculo?
Los paquetes, como de costumbre, son una forma bastante común de organizar clases por espacio de nombres. Pero su ventaja no es solo esto, en Java también actúan como un medio para limitar la visibilidad de las clases y sus miembros.
Permítame recordarle que en Java hay 4 categorías diferentes que le permiten distinguir entre la visibilidad. Solo hay dos de ellos para las clases: son visibles dentro del paquete (paquete privado) o completamente abiertos (público). Pero el método o campo ya puede hacerse privado (no será accesible fuera de la clase) visible solo para el paquete (paquete privado), puede hacerse para que el método sea adicionalmente visible para los herederos, tanto en su paquete como fuera del paquete (protegido), y También puede hacerlo visible para todos (público).
Java 9 introdujo la capacidad de dividir el código en módulos, y ahora es posible hacer que una parte del código sea visible en todas partes dentro del módulo, pero no desde el exterior. Y resulta ser muy útil para construir una API sensible.
En una palabra, las opciones en Java son más que suficientes. Pero en Kotlin, por alguna razón, se limitaron a introducir visibilidad pública y privada, así como visibilidad para los herederos. Además, sin embargo, introdujeron una distinción por módulos, pero se hizo imposible diferenciar el acceso a los métodos y clases por paquetes. Un módulo ya no es una construcción del lenguaje en sí mismo, y muy a menudo las personas entienden cosas muy diferentes con este término. Kotlin define oficialmente el módulo como "un
conjunto de archivos Kotlin compilados juntos ".
El problema es que el módulo, como regla, conduce a costos de recursos adicionales. Al mismo tiempo, si crea un paquete separado y coloca clases en él con funciones que solo son visibles en este paquete, no hay problemas, porque todos los paquetes se compilarán juntos y no se necesitarán recursos adicionales.
Esto es especialmente pronunciado si, por ejemplo, recopila proyectos en Gradle, como de costumbre, las aplicaciones de Android están ensambladas. Los módulos generalmente se hacen relativamente grandes para que sean una unidad funcional completa. Dentro de un módulo, un método no puede hacerse visible para uno y no visible para otras clases. Y si queremos que la apariencia de los métodos sea más granular, surge un problema.
Aquí, quiero recordar de inmediato los paquetes, porque en Kotlin esta esencia no ha desaparecido, pero, por desgracia, no afecta la visibilidad. Por supuesto, siempre puedes hacer más módulos, pero, dadas las características de Gradle, esto es simplemente irracional: la velocidad de construcción disminuirá. Sí, es posible poner clases en un archivo, pero en el caso de un proyecto grande, el archivo se volverá realmente "pesado". Por lo tanto, me gustaría obtener alguna otra forma de ocultar métodos, por ejemplo, modelados en Java.
No lo procese ... incluso si fuera necesario
El segundo es bastante controvertido (porque algunos consideran que su uso es una mala noticia), pero, sin embargo, lo negativo es la ausencia de excepciones comprobadas. Estas herramientas están en Java, pero Kotlin decidió no implementarlas. La
documentación oficial tiene un ejemplo sobre la interfaz Appendable. Puede adjuntar cadenas al Appendable, y dado que las cadenas se pueden conectar a objetos relacionados con E / S, por ejemplo, al escribir en un archivo o en la red, puede obtener una IOException al llamar a métodos de interfaz. Y tales casos hacen que el uso de excepciones marcadas sea inconveniente.
Los creadores del lenguaje explican su argumento de la siguiente manera: si usamos StringBuilder, accediendo a él a través de Appendable, resulta que necesitamos manejar una IOException, incluso si está seguro de que no puede suceder en principio:
Appendable log = new StringBuilder(); try { log.append(message); } catch (IOException e) {
Salida de la situación: la excepción está "atrapada", pero no hacen nada al respecto, lo que, por supuesto, no es bueno. Sin embargo, surge la pregunta: si obviamente trabajamos con StringBuilder a través de la interfaz Appendable, ¿por qué no interactuar directamente con StringBuilder? Hay una diferencia importante: cuando trabajamos con Appendable, si no sabemos qué implementación específica se encuentra debajo, la excepción de entrada / salida se vuelve realmente posible, pero StringBuilder no lo dará exactamente, y los métodos correspondientes se declaran en él, aunque implementar la interfaz Entonces el ejemplo es bastante ajustado ...
Es particularmente interesante que los autores de la documentación se refieran al Capítulo 77 en Java Efectivo, que establece que las excepciones no pueden ser capturadas e ignoradas. Pero solo en los siguientes capítulos está escrito que las excepciones marcadas pueden y deben usarse si se hacen con prudencia. Si se cita de manera selectiva, cualquier punto de vista puede justificarse.
Como resultado, los desarrolladores de Kotlin lograron que, en esencia, todos los métodos pudieran generar algún tipo de excepción. Pero entonces, ¿dónde están las herramientas para manejar errores en el nuevo idioma? ¿Cómo entender ahora dónde podría aparecer una excepción? A nivel de lenguaje, por desgracia, no encontramos ayuda en estos asuntos, e incluso con el código fuente (que está lejos de estar siempre disponible sin tener en cuenta varios trucos), es difícil entender qué hacer en cada situación específica.
Si hace una pregunta a los desarrolladores, simplemente se encogen de hombros y dicen que
en otros idiomas no hay excepciones comprobadas y nada , también crean programas grandes y confiables. Pero también se escriben con éxito en idiomas francamente fallidos, esto no es un argumento. En StackOverflow, dicen a una pregunta similar que "
necesita leer la documentación ", una buena respuesta, muy conveniente en tales situaciones. Solo la documentación puede no existir, puede estar incompleta o desactualizada; el compilador no la verifica. Finalmente, es posible que no encuentre la respuesta en él.
Sí, es cierto que haber verificado las excepciones puede generar API inconvenientes. Cuando la comprobación de excepciones es obviamente redundante para que el compilador esté "satisfecho", debe escribir try ... catch y en realidad solo crear código basura, porque no se hace nada al procesar estas excepciones. Y el hecho de que es inconveniente usarlos en código funcional también es cierto. Pero las excepciones marcadas son solo una herramienta que se puede utilizar de la misma manera competente, cuando sea necesario.
No está claro por qué el lenguaje aprovechó esta oportunidad, si la filosofía de Kotlin es confiar más herramientas al programador (al menos eso nos pareció), y si el autor del código puede describir correctamente dónde habrá excepciones, ¿por qué no creerle? Tome los mismos operadores sobrecargados que se eliminaron de Java, ya que pueden conducir a la aparición de API con acciones no obvias: esto era para proteger a los programadores de ellos mismos. Kotlin, por el contrario, tiene la capacidad de sobrecargar a los operadores y hacer muchas otras cosas, entonces, ¿por qué no hay excepciones comprobadas? ¿Podrían los creadores haberlo hecho porque simplemente no era como en Java?
Estamos esperando el cambio ...
El máximo con el que podemos contar bajo Android es Java 7 o Java 8 (pero con algunas limitaciones y advertencias), mientras que Java 11 ya se acerca. Usando Kotlin, la programación en Android es mucho más fácil, la cantidad de líneas de texto se reduce .
Uno solo puede esperar que los desarrolladores complementen este lenguaje muy útil con aquellas características que no están disponibles hoy por razones obvias. Tal vez en futuras versiones habrá nuevas herramientas para analizar excepciones en el IDE, así como nuevas categorías de privacidad. Pero, aparentemente, este es el caso en el mejor caso del futuro lejano, ya que los desarrolladores del lenguaje ni siquiera han expresado ninguna promesa.