A aparência do Kotlin é um bônus importante para os desenvolvedores. Uma linguagem de alto nível que se integra perfeitamente ao Java expande bastante os recursos dos programadores. No entanto, em qualquer idioma, encontramos constantemente alguns problemas, que, pelo contrário, criam restrições, e Kotlin, é claro, não foi exceção. Hoje falaremos sobre eles.

Kotlin estava entusiasmado com a comunidade, pois a nova linguagem de programação simplifica bastante a escrita de código, substituindo o Java. Isso é especialmente perceptível no Android, onde novas versões do Java aparecem, para dizer o mínimo, "com um rangido". Muitos dispositivos são atualizados com longos atrasos, ainda mais - eles não recebem atualizações de firmware. Na melhor das hipóteses, o suporte para o dispositivo termina cerca de 2 anos após seu lançamento, o que promete uma, no máximo duas atualizações do sistema. No entanto, as pessoas continuam usando dispositivos, o que significa que os desenvolvedores precisam confiar no Android 8 (até agora) mais recente e no Android 5, ou mesmo versões anteriores, onde certamente não há apenas a mais recente, mas também a implementação atual do Java. Para referência, agora o compartilhamento total do Android 7 e 8 - aquelas versões em que o Java 8 é suportado pelas bibliotecas do sistema - é de 42,9%, o restante é o Java 7.
Alguns podem dizer que o Java está obsoleto. Mas há também uma opinião de que Java é uma linguagem que é boa "como está" e não deve ser tocada. É como um MDC (o maior fator comum) em matemática. Ele contém um conjunto de funções de cavalheiros e, para aqueles que precisam de recursos adicionais hoje em dia, estão disponíveis idiomas especiais que já funcionam sobre a JVM. Muitas dessas linguagens já foram criadas: Scala, Clojure, JRuby, Jython, Groovy e outras, menos conhecidas. No entanto, Kotlin tem uma série de vantagens. Essa linguagem deixa ao programador mais liberdade: permite usar fragmentos prontos em Java ao mesmo tempo, combinando código antigo e novo.
Mas com todas as vantagens da nova linguagem, que de nenhuma maneira contestamos, durante o processo de desenvolvimento, algumas desvantagens foram encontradas nela. E hoje seria interessante ouvir a opinião dos colegas sobre se eles interferem no trabalho da mesma maneira que nós.
Não é possível ocultar o programa?
Pacotes, como sempre, são uma maneira bastante comum de organizar classes por namespace. Mas a vantagem deles não é apenas isso, em Java eles também atuam como um meio de limitar a visibilidade das classes e de seus membros.
Deixe-me lembrá-lo que em Java existem 4 categorias diferentes que permitem distinguir entre visibilidade. Existem apenas dois deles para classes - eles são visíveis no pacote (pacote privado) ou completamente aberto (público). Mas o método ou campo já pode ser tornado privado (não estará acessível fora da classe), visível apenas para o pacote (pacote privado), pode ser feito para que o método seja visível adicionalmente aos herdeiros, tanto no pacote como fora do pacote (protegido), e Você também pode torná-lo visível para todos (público).
O Java 9 introduziu a capacidade de dividir o código em módulos, e agora é possível tornar parte do código visível em qualquer lugar dentro do módulo, mas não de fora. E acaba sendo muito útil para criar uma API sensata.
Em uma palavra, as opções em Java são mais que suficientes. Mas em Kotlin, por algum motivo, eles se limitaram a introduzir visibilidade pública e privada, bem como visibilidade para os herdeiros. Além disso, eles introduziram uma distinção por módulos, mas tornou-se impossível diferenciar o acesso a métodos e classes por pacotes. Um módulo não é mais uma construção da própria linguagem, e muitas vezes as pessoas entendem coisas bastante diferentes por esse termo. Kotlin define oficialmente o módulo como "um
conjunto de arquivos Kotlin compilados juntos ".
O problema é que o módulo, via de regra, leva a custos adicionais de recursos. Ao mesmo tempo, se você criar um pacote separado e colocar classes nele com funções visíveis apenas neste pacote, não haverá problemas, porque todos os pacotes serão compilados juntos e nenhum recurso adicional será necessário.
Isso é especialmente pronunciado se, por exemplo, você coleta projetos em Gradle, como de costume, os aplicativos Android são montados. Os módulos são geralmente feitos relativamente grandes, de modo que eles são uma unidade funcional completa. Dentro de um módulo, um método não pode ser tornado visível para um e nem para outras classes. E se queremos tornar a aparência dos métodos mais granular, surge um problema.
Aqui, eu quero imediatamente lembrar os pacotes, porque no Kotlin essa essência não desapareceu, mas, infelizmente, não afeta a visibilidade. Obviamente, você sempre pode criar mais módulos, mas, considerando os recursos do Gradle, isso é simplesmente irracional: a velocidade de construção diminuirá. Sim, é possível colocar classes em um arquivo, mas no caso de um projeto grande, o arquivo se tornará realmente "pesado". Portanto, gostaria de obter outra maneira de ocultar métodos, por exemplo, modelados em Java.
Não processe ... mesmo que fosse necessário
O segundo é bastante controverso (porque alguns consideram seu uso uma má notícia), mas, no entanto, o menos é a ausência de exceções verificadas. Essas ferramentas estão em Java, mas a Kotlin decidiu não implementá-las. A
documentação oficial tem um exemplo sobre a interface Appendable. Você pode anexar cadeias de caracteres ao Appendable e, como as cadeias de caracteres podem se conectar a objetos relacionados à E / S, por exemplo, ao gravar em um arquivo ou na rede, é possível obter uma IOException ao chamar métodos de interface. E esses casos tornam inconveniente o uso de exceções verificadas.
Os criadores da linguagem explicam seu argumento da seguinte maneira: se usarmos o StringBuilder, acessando-o através do Appendable, acontece que precisamos manipular uma IOException, mesmo se você tiver certeza de que basicamente isso não pode acontecer:
Appendable log = new StringBuilder(); try { log.append(message); } catch (IOException e) {
Saída da situação: a exceção é "capturada", mas eles não fazem nada com ela, o que, é claro, não é bom. No entanto, surge a pergunta: se obviamente trabalhamos com o StringBuilder por meio da interface Appendable - por que não interagimos diretamente com o StringBuilder? Há uma diferença importante: ao trabalhar com o Appendable, se não soubermos qual implementação específica existe, uma exceção à E / S se tornará realmente possível, mas o StringBuilder não fornecerá exatamente, e os métodos correspondentes serão declarados nela, embora eles implementar a interface. Então, o exemplo é bem apertado ...
É particularmente interessante que os autores da documentação se refiram ao Capítulo 77 em Java Efetivo, que afirma que as exceções não podem ser capturadas e ignoradas. Mas somente nos próximos capítulos está escrito que as exceções verificadas podem e devem ser usadas se forem feitas com sabedoria. Se assim for citado seletivamente, qualquer ponto de vista pode ser justificado.
Como resultado, os desenvolvedores do Kotlin fizeram com que, em essência, todos os métodos pudessem gerar algum tipo de exceção. Mas então, onde estão as ferramentas para lidar com erros no novo idioma? Como agora entender onde uma exceção pode aparecer? No nível do idioma, infelizmente, não encontramos ajuda nessas questões e, mesmo com o código-fonte (que está longe de estar sempre disponível sem levar em conta vários truques), é difícil entender o que fazer em cada situação específica.
Se você fizer uma pergunta aos desenvolvedores, eles simplesmente dão de ombros e dizem que
em outros idiomas não há exceções verificadas e nada , eles também criam programas grandes e confiáveis. Mas eles também são escritos com sucesso em idiomas francamente malsucedidos, isso não é um argumento. No StackOverflow, eles dizem para uma pergunta semelhante que “
você precisa ler a documentação ” - uma boa resposta, muito conveniente em tais situações. Somente a documentação pode não existir, pode estar incompleta ou desatualizada - o compilador não a verifica. Finalmente, você pode não encontrar a resposta.
Sim, é verdade que ter verificado exceções pode levar a APIs inconvenientes. Quando a verificação de exceções é obviamente redundante, para que o compilador seja "satisfeito", você deve escrever try ... catch e, na verdade, apenas criar código indesejado, porque nada é feito ao processar essas exceções. E o fato de ser inconveniente usá-los no código funcional também é verdadeiro. Mas as exceções verificadas são apenas uma ferramenta que pode ser usada com a mesma competência, quando necessário.
Não está claro por que a linguagem aproveitou essa oportunidade, se a filosofia de Kotlin é confiar mais ferramentas ao programador (pelo menos nos pareceu) e se o autor do código pode descrever corretamente onde haverá exceções, por que não acreditar nele? Pegue os mesmos operadores sobrecarregados que foram removidos do Java, porque eles podem levar ao surgimento de APIs com ações não óbvias - isso era para proteger os programadores de si mesmos. Kotlin, por outro lado, tem a capacidade de sobrecarregar os operadores e fazer muitas outras coisas - então por que não há exceções verificadas? Os criadores poderiam ter feito isso porque simplesmente não era como em Java?
Estamos aguardando mudanças ...
O máximo com o qual podemos contar no Android é Java 7 ou Java 8 (mas com algumas limitações e ressalvas), enquanto o Java 11. já está se aproximando.Com o Kotlin, programar no Android é muito mais fácil, o número de linhas de texto é reduzido .
Só podemos esperar que os desenvolvedores complementem essa linguagem muito útil com os recursos que não estão disponíveis hoje por razões óbvias. Talvez em versões futuras haja novas ferramentas para analisar exceções no IDE, bem como novas categorias de privacidade. Mas, aparentemente, esse é o caso no melhor caso de um futuro distante, uma vez que os desenvolvedores de idiomas nem sequer fizeram promessas.