Kotlin: zwei Löffel Teer in einem Fass Honig

Das Erscheinen von Kotlin ist ein wichtiger Bonus für Entwickler. Eine Hochsprache, die sich nahtlos in Java integriert, erweitert die Fähigkeiten von Programmierern erheblich. In jeder Sprache stoßen wir jedoch ständig auf Probleme, die im Gegenteil zu Einschränkungen führen, und Kotlin war natürlich keine Ausnahme. Wir werden heute darüber sprechen.



Kotlin war von der Community begeistert, da die neue Programmiersprache das Schreiben von Code erheblich vereinfacht und Java ersetzt. Dies macht sich insbesondere bei Android bemerkbar, wo neue Versionen von Java erscheinen, um es milde auszudrücken, „mit einem Knarren“. Viele Geräte werden mit langen Verzögerungen aktualisiert, noch mehr - sie erhalten überhaupt keine Firmware-Updates. Im besten Fall endet die Unterstützung für das Gerät etwa zwei Jahre nach seiner Veröffentlichung, was ein, maximal zwei Systemupdates verspricht. Die Benutzer verwenden jedoch weiterhin Geräte, was bedeutet, dass Entwickler sich sowohl auf das (bisher) neueste Android 8 als auch auf Android 5 oder sogar frühere Versionen verlassen müssen, bei denen es sicherlich nicht nur die neueste, sondern auch die aktuelle Implementierung von Java gibt. Als Referenz beträgt der Gesamtanteil von Android 7 und 8 - jene Versionen, in denen Java 8 von Systembibliotheken unterstützt wird - 42,9%, der Rest ist Java 7.

Einige könnten sagen, dass Java veraltet ist. Es gibt aber auch die Meinung, dass Java eine Sprache ist, die so wie sie ist gut ist und nicht berührt werden sollte. Es ist wie eine GCD (der größte gemeinsame Faktor) in der Mathematik. Es enthält eine Reihe von Funktionen für Herren, und für diejenigen, die heute zusätzliche Funktionen benötigen, stehen spezielle Sprachen zur Verfügung, die bereits über die JVM hinaus funktionieren. Viele dieser Sprachen haben bereits gezüchtet: Scala, Clojure, JRuby, Jython, Groovy und andere, weniger bekannte. Kotlin hat jedoch eine Reihe von Vorteilen. Diese Sprache lässt dem Programmierer mehr Freiheit: Sie können gleichzeitig vorgefertigte Fragmente in Java verwenden und alten und neuen Code kombinieren.

Bei all den Vorteilen der neuen Sprache, die wir in keiner Weise bestreiten, wurden während des Entwicklungsprozesses einige Nachteile festgestellt. Und heute wäre es interessant, die Meinung von Kollegen darüber zu hören, ob sie die Arbeit genauso stören wie wir.

Kann Show nicht verstecken?


Pakete sind wie üblich eine weit verbreitete Methode, um Klassen nach Namespace zu organisieren. Ihr Plus ist jedoch nicht nur das. In Java dienen sie auch dazu, die Sichtbarkeit von Klassen und ihren Mitgliedern einzuschränken.

Ich möchte Sie daran erinnern, dass es in Java 4 verschiedene Kategorien gibt, mit denen Sie zwischen Sichtbarkeit unterscheiden können. Es gibt nur zwei davon für Klassen - sie sind entweder innerhalb des Pakets (Paket privat) oder vollständig offen (öffentlich) sichtbar. Die Methode oder das Feld kann jedoch bereits privat gemacht werden (es ist außerhalb der Klasse nicht zugänglich) und nur für das Paket sichtbar (Paket privat). Es kann so gemacht werden, dass die Methode für die Erben sowohl in ihrem Paket als auch außerhalb des Pakets (geschützt) zusätzlich sichtbar ist Sie können es auch für alle sichtbar machen (öffentlich).

Mit Java 9 wurde die Möglichkeit eingeführt, Code in Module aufzuteilen. Jetzt ist es möglich, einen Teil des Codes überall im Modul sichtbar zu machen, jedoch nicht von außen. Und es erweist sich als sehr nützlich, um eine sinnvolle API zu erstellen.

Mit einem Wort, Optionen in Java sind mehr als genug. Aber aus irgendeinem Grund beschränkten sie sich in Kotlin darauf, öffentliche und private Sichtbarkeit sowie Sichtbarkeit für die Erben einzuführen. Darüber hinaus wurde jedoch eine Unterscheidung nach Modulen eingeführt, aber es wurde unmöglich, den Zugriff auf Methoden und Klassen nach Paketen zu unterscheiden. Ein Modul ist nicht länger eine Konstruktion der Sprache selbst, und oft verstehen Menschen unter diesem Begriff ganz andere Dinge. Kotlin definiert das Modul offiziell als "eine Reihe von Kotlin-Dateien, die zusammen kompiliert wurden ".

Der Haken ist, dass das Modul in der Regel zu zusätzlichen Ressourcenkosten führt. Wenn Sie ein separates Paket erstellen und Klassen mit Funktionen einfügen, die nur in diesem Paket sichtbar sind, treten gleichzeitig keine Probleme auf, da alle Pakete zusammen kompiliert werden und keine zusätzlichen Ressourcen erforderlich sind.

Dies ist besonders ausgeprägt, wenn Sie beispielsweise Projekte in Gradle sammeln. Wie üblich werden Android-Anwendungen zusammengestellt. Module werden normalerweise relativ groß gemacht, so dass sie eine vollständige Funktionseinheit darstellen. Innerhalb eines Moduls kann eine Methode nicht für eine Klasse sichtbar und für andere Klassen nicht sichtbar gemacht werden. Und wenn wir das Erscheinungsbild von Methoden detaillierter gestalten wollen, entsteht ein Problem.

Hier möchte ich sofort an die Pakete erinnern, da diese Essenz in Kotlin nicht verschwunden ist, aber leider die Sichtbarkeit nicht beeinträchtigt. Natürlich können Sie immer mehr Module erstellen, aber angesichts der Funktionen von Gradle ist dies einfach irrational: Die Erstellungsgeschwindigkeit nimmt ab. Ja, es ist möglich, Klassen in eine Datei einzufügen, aber bei einem großen Projekt wird die Datei sehr "schwer". Daher möchte ich eine andere Möglichkeit zum Ausblenden von Methoden erhalten, beispielsweise nach dem Vorbild von Java.

Verarbeiten Sie es nicht ... auch wenn es notwendig wäre


Die zweite ist ziemlich kontrovers (weil einige ihre Verwendung als schlechte Nachricht betrachten), aber das Minus ist das Fehlen überprüfter Ausnahmen. Diese Tools sind in Java, aber Kotlin hat beschlossen, sie nicht zu implementieren. Die offizielle Dokumentation enthält ein Beispiel für die anhängbare Benutzeroberfläche. Sie können Zeichenfolgen an das Anhängen anhängen. Da Zeichenfolgen eine Verbindung zu Objekten herstellen können, die sich auf E / A beziehen, z. B. beim Schreiben in eine Datei oder in das Netzwerk, können Sie beim Aufrufen von Schnittstellenmethoden möglicherweise eine IOException erhalten. In solchen Fällen ist die Verwendung geprüfter Ausnahmen unpraktisch.

Die Ersteller der Sprache erklären ihre Argumentation wie folgt: Wenn wir StringBuilder verwenden und über Appendable darauf zugreifen, stellt sich heraus, dass wir eine IOException behandeln müssen, auch wenn Sie sicher sind, dass dies grundsätzlich nicht möglich ist:

Appendable log = new StringBuilder(); try {    log.append(message); } catch (IOException e) {    // Must be safe } 

Ausweg aus der Situation: Die Ausnahme ist "erwischt", aber sie machen nichts damit, was natürlich nicht gut ist. Es stellt sich jedoch die Frage: Wenn wir offensichtlich über die Appendable-Schnittstelle mit StringBuilder arbeiten, warum nicht direkt mit StringBuilder interagieren? Es gibt einen wichtigen Unterschied: Wenn wir bei der Arbeit mit Appendable nicht wissen, welche spezifische Implementierung darunter liegt, wird die Ausnahme der Eingabe / Ausgabe wirklich möglich, aber StringBuilder gibt sie nicht genau an, und die entsprechenden Methoden werden darin deklariert, obwohl sie Implementieren Sie die Schnittstelle. Das Beispiel ist also ziemlich eng ...

Es ist besonders interessant, dass die Autoren der Dokumentation auf Kapitel 77 in Effective Java verweisen, in dem angegeben wird, dass Ausnahmen nicht abgefangen und ignoriert werden können. Aber nur in den nächsten Kapiteln wird geschrieben, dass geprüfte Ausnahmen verwendet werden können und sollten, wenn sie mit Bedacht durchgeführt werden. Wenn dies selektiv zitiert wird, kann jeder Standpunkt gerechtfertigt werden.

Infolgedessen haben die Kotlin-Entwickler es so gemacht, dass im Wesentlichen alle Methoden möglicherweise eine Ausnahme auslösen können. Aber wo sind dann die Werkzeuge zur Behandlung von Fehlern in der neuen Sprache? Wie kann man jetzt verstehen, wo eine Ausnahme auftreten könnte? Auf Sprachebene finden wir leider keine Hilfe in diesen Angelegenheiten, und selbst mit dem Quellcode (der bei weitem nicht immer verfügbar ist, ohne verschiedene Tricks zu berücksichtigen) ist es schwierig zu verstehen, was in der jeweiligen Situation zu tun ist.

Wenn Sie den Entwicklern eine Frage stellen, zucken sie einfach mit den Schultern und sagen, dass es in anderen Sprachen keine geprüften Ausnahmen gibt und nichts , sie erstellen auch große und zuverlässige Programme. Sie werden aber auch erfolgreich in offen erfolglosen Sprachen geschrieben, dies ist kein Argument. Bei StackOverflow heißt es zu einer ähnlichen Frage: „ Sie müssen die Dokumentation lesen “ - eine gute Antwort, die in solchen Situationen sehr praktisch ist. Nur die Dokumentation ist möglicherweise nicht vorhanden, sie ist möglicherweise unvollständig oder veraltet - der Compiler überprüft sie nicht. Schließlich finden Sie möglicherweise keine Antwort darin.

Ja, es stimmt, dass das Überprüfen von Ausnahmen zu unbequemen APIs führen kann. Wenn die Suche nach Ausnahmen offensichtlich redundant ist, damit der Compiler „zufrieden“ ist, müssen Sie try ... catch schreiben und tatsächlich nur Junk-Code erstellen, da bei der Verarbeitung dieser Ausnahmen nichts unternommen wird. Und die Tatsache, dass es unpraktisch ist, sie im Funktionscode zu verwenden, ist auch wahr. Überprüfte Ausnahmen sind jedoch nur ein Werkzeug, das bei Bedarf genauso kompetent eingesetzt werden kann.

Es ist unklar, warum die Sprache diese Gelegenheit genutzt hat, wenn Kotlins Philosophie darin besteht, dem Programmierer mehr Werkzeuge anzuvertrauen (zumindest schien es uns), und wenn der Autor des Codes richtig beschreiben kann, wo es Ausnahmen geben wird, warum sollte er ihm nicht glauben? Nehmen Sie dieselben überladenen Operatoren, die aus Java entfernt wurden, da sie zur Entstehung von APIs mit nicht offensichtlichen Aktionen führen können - dies diente dazu, Programmierer vor sich selbst zu schützen. Im Gegensatz dazu kann Kotlin Bediener überlasten und viele andere Dinge tun - warum gibt es also keine geprüften Ausnahmen? Könnten die Schöpfer es getan haben, weil es einfach nicht wie in Java war?

Wir warten auf Veränderung ...


Das Maximum, auf das wir unter Android zählen können, ist Java 7 oder Java 8 (jedoch mit einigen Einschränkungen und Einschränkungen), während sich Java 11 bereits nähert. Mit Kotlin ist das Programmieren unter Android viel einfacher, die Anzahl der Textzeilen wird reduziert .

Man kann nur hoffen, dass die Entwickler diese sehr nützliche Sprache mit den Funktionen ergänzen, die heute aus offensichtlichen Gründen nicht verfügbar sind. Möglicherweise gibt es in zukünftigen Versionen neue Tools zum Analysieren von Ausnahmen in der IDE sowie neue Datenschutzkategorien. Aber anscheinend ist dies im besten Fall der fernen Zukunft der Fall, da die Sprachentwickler nicht einmal irgendwelche Versprechungen gemacht haben.

Source: https://habr.com/ru/post/de418377/


All Articles