Fragen für die Zukunft

Cromon

Erfahrenes Mitglied
Hallo zusammen

Für einige Projekte an denen ich in Zukunft arbeiten werde bin ich an die Plattform Android gebunden. Ein grösseres Projekt habe ich dafür bereits mit Java abgeschlossen und musste wieder einmal feststellen, dass ich kein Javamensch bin und das auch nie war. Für mich stellt sich jetzt die Frage ob ich es vielleicht in Zukunft werde, oder ob ich mich nach C# bzw C++ Alternativen für Android umsehe. Das liegt vor allem an der Sprache selber, weniger daran was im Hintergrund oder in der IDE oder sonst wo läuft. Dabei habe ich versucht ein bisschen was über die Zukunft von Java via google zu sammeln, allerdings bin ich da nicht wirklich auf einen grünen Zweig gekommen (bzw viele widersprüchliche oder vage Angaben). So bin ich mir zum Beispiel nicht wirklich sicher ob zwischen Java 6 und Java 7 wirklich fast 6 Jahre lagen und dabei eigentlich nichts nennenswertes bei der Sprache verbessert wurde. Das einzige was ich herausfinden konnte ist, dass der Grundtenor ist, die Sprache müsste an vielen Ecken und Enden mal auf den neusten Stand gebracht werden, da allerdings noch nicht wirklich was passiert ist.

Im allgemeinen gibt es für mich einige Kernelemente die mich eigentlich fast täglich aufregen bzw ich nicht nachvollziehen kann und genau da wollte ich fragen ob vielleicht jemand von euch bisschen was mehr weiss, wie sich da die Sprache so entwickeln wird.

  • Events/Delegate vs Interfaces:
    Interfaces (und damit das Beobachterprinzip) sind eine nette Sache, führen aber an vielen Stellen einfach zu aufgeblasenem Code. Es gibt nunmal Komponenten die für die Kommunikation nur ein paar wenige Funktionen benötigen, entsprechend hat man dann unzählige kleine Interfaces die man irgendwo verstauen muss. Für jedes eine eigene Datei zu verwenden bläht den Solutiontree enorm auf, wenn man verschiedene Interfaces versucht irgendwie zu kreuzen fühlt sich das auch irgendwie falsch an und sie als eingebetteten Typ einer anderen Klasse zu machen ist keine Alternative, der Code ist schon schlimm genug weil man (wie in C#) Deklaration und Implementation nicht so wie in C++ sauber trennen kann.

    Daneben sind Events bzw Delegate viel flexibler als Interfaces. Für den Provider an sich ändert sich einerseits die Tatsache, dass er sich nicht darum kümmern muss wer jetzt effektiv einem beobachtet andererseits ist er von jeglichen Voraussetzungen befreit und hat sich nicht einen Deut darum zu kümmern was er da jetzt aufruft (sei es nativer Code, eine statische Funktion, eine Memberfunktion, eine dynamische Methode, ...) während bei einem Interface alles auf eine Memberfunktion beschränkt wird. Das macht es auch für den Listener viel einfacher, er kann alles mögliche übergeben, es muss nur irgendwie aufrufbar sein.
  • Generics:
    Bei diesem Punkt muss ich ehrlich sagen bin ich extrem enttäuscht von Java. Generics machen das Leben nicht einfacher, sie sind auf englisch gesagt einfach "pain in the ass". Ich bin vollkommen einverstanden mit dem Ansatz, dass die Generics so wenig Einfluss auf die Laufzeit haben sollen wie möglich, aber dann bitte gleich so machen wie in C++, template Typen werden während der Compilierung einfach 1:1 durch den Typnamen ersetzt und nicht so wie in Java durch irgendwie etwas merkwürdiges das weder Hand noch Fuss hat. Wenn ich nichtmal statische Methoden für einen generischen Typen verwenden kann weiss einfach auch nicht mehr weiter. So wie es aktuell ist hat man die Nachteile aus C# genommen und sie mit den Nachteilen aus C++ kombiniert und so dann Generics erstellt. Hier wünsche ich mir eine konzeptionelle Änderung, generischer Code ist für mich extrem wichtig.
  • Unverständlich unhandliche Collection:
    Collections arbeiten praktisch überhaupt nicht miteinander, sind inkompatibel, wenn man noch Arrays hinzu nimmt geht grad gar nichts mehr. Hier wünsche ich mir Sachen wie in C#
C#:
byte[] someArray = getArray();
List<SomeObject> list = someArray.Where(b => (b % 2) == 0).Select(b => new SomeObject(b)).ToList();
  • Abschaffung der primitiven und nicht-primitiven Varianten gewisser Typen. int ist ein Integer und ein Integer ist ein int, das sind einfach Synonyme füreinander. Wer sie wie Objekte haben will kann Nullable<int> verwenden.

Es würde mich freuen, wenn vielleicht der eine oder andere etwas dazu wüsste und mich daran teilhaben könnte.

Grüsse
Cromon
 
Zuletzt bearbeitet:

genodeftest

Erfahrenes Mitglied
Hi
Java 6 ist im Herbst 2006 erschienen, Java 7 am 28. Juli 2011, also fast 5 Jahre später. Von Java 6 auf Java 7 hat sich nicht viel an der Sprache, das ist richtig. Gründe dafür gibt es viele, z.B. dass in diesen Zeitraum die Übernahme von Sun durch Oracle sowie die Umstellung auf eine etwas offenere Entwicklung stattgefunden hat. Bis Java 6 war die Standardbibliothek sowie die Virtual Machine von Sun größtenteils proprietär, jetzt ist sie in Form des OpenJDK-Projekts vollständig open source, die Sprache selbst sogar unter der GPL verfügbar. Es gibt weiterhin proprietären Code, der in manchen Varianten mitgeliefert wird. Außerdem hat sich der Standardisierungsprozess verändert, so dass auch externe Personen/Unternehmen (außer Oracle) bei Entscheidungen über die Programmiersprache mit einbezogen werden.

Zu den einzelnen Punkten:
1. Events/Delegates vs. Interfaces:
Das ist in der Tat ein Schwachpunkt der Programmiersprache Java. Für Java 8 ist die Einführung von Lambda-Ausdrücken geplant, die das vereinfachen (so weit ich weiß). Prinzipiell gibt es aber auch Actions (~Events), die z.B. in Swing auch umfangreich implementiert sind.
Für das angesprochene Problem der Trennung von Deklaration und Implementation bietet es sich in Java an, ein Interface bereit zu stellen, das die Deklaration beinhaltet. Dazu kommt dann eine Abstrakte Klasse, in die der allgemeine Code rein kommt und dann abgeleitete Klassen, in denen die Details der Implementation vorgenommen werden. In größeren Software-Frameworks wie Eclipse ist das sehr üblich. Beispiel:
Interface A
abstrakte Klasse AbstractA
abgeleitete Klassen AImpl1, AImpl2, …
Innerhalb der Java SE API trifft das zum Beispiel auf das Collection-Framework zu: java.util.List ist das Interface, java.util.AbstractList enthält den Code einer allgemeinen Implementierung und dann gibt es z.B. die abgeleitete Klasse java.util.LinkedList.
Irgendwann für die Zukunft sind aber auch Interfaces geplant, die Code enthalten können – Details dazu müsstest du dir aber selber suchen, z.B. unter http://www.tutego.de/blog/javainsel/ und http://openjdk.java.net/

2. Generics:
Im Gegensatz zu den Templates (die du wahrscheinlich meinst) in C++ sind Generics in Java darauf ausgelegt, dass sie zum Einen groß skalieren (geringerer Speicherverbrauch für große Datenmengen verschiedener Objekte zur Laufzeit) und zum Anderen immer Typsicherheit garantieren. Deswegen können die Typen in generische Klassen nicht zur Compilezeit festgeschrieben werden, sondern eben erst zur Laufzeit. Weiterhin gibt es Features in Java, zur Laufzeit Code zu ändern (und damit z.B. neue Klassen hinzuzufügen), was mit der Festlegung der generischen Typen zur Compilezeit nicht vereinbar ist.
Statische Methoden können Generics verwenden, siehe dieses Beispiel:
Java:
<T> T getTest(final T t) {
		return t;
	}
Vielleicht fehlen dir einfach nur die Grundlagen zum Verständnis von Generics. Generics machen meiner Meinung nach das Leben deutlich einfacher, weil sie Typsicherheit zu jedem Zeitpunkt erlauben, ohne die Performance maßgeblich zu beeinflussen.

3. unverständlich unhandliche Collection:
Dieses Beispiel ist nicht einfach in Java umzusetzen, da hast du Recht. Das Collection-Framework ist aber auch nicht darauf ausgelegt, im großen Maßstab mit primitiven Datentypen zu arbeiten. Mit nicht-primitiven Datentypen sind solche Konstrukte aber auch in C# nur begrenzt möglich bzw. werden sehr schnell sehr unübersichtlich. Für solche Probleme verwendet man in Java Iteratoren. Da die meisten Collections Iterable sind, d.h. einen Iterator anbieten, lässt sich solcher Code trotzdem kurz und gleichzeitig übersichtlich fassen.
Dass Collections nicht miteinander arbeiten oder gar inkompatibel sind, kann ich nicht bestätigen. Die Schnittstellen List, Queue und Set bieten jeweils die Methode toArray() an, in der Klasse Arrays gibt es die Methode asList(), in der Klasse Collections gibt es einige weitere hilfreiche Funktionen. Welche Funktionalität fehlt dir denn? Hast du dir schon mal Klassen wie java.util.Collections und java.util.Arrays angesehen?

4. Aus Performancegründen (v.a. Speicherverbrauch) gibt es die primitiven Datentypen wie int noch. Ein bisschen sind diese Gründe auch nur historisch, Java ist ja auch schon knapp 20 Jahre alt.
int und Integer ist nicht das gleiche. int ist ein primitiver Typ, der damit immer mittels Call-by-Value übergeben wird. Integer ist ein Referenztyp, der immer mittels Call-by-Reference übergeben wird und auch ein Zeiger auf null sein kann. Die aktuelle Version von Java lässt den Nutzer nur nicht mehr viel davon merken, weil mit Hilfe von Boxing/Unboxing die Typen ineinander umgewandelt werden, was in manchen (eindeutigen) Fällen auch implizit funktioniert (Autoboxing/Autounboxing).
 

Akeshihiro

Erfahrenes Mitglied
Die gesamte Collection-API wurde für Java8 durch die virtuellen Methoden in Interfaces erweitert und überarbeitet. Damit lassen sich dann ebenso solche Spielereien bewerkstelligen. Ansonsten hat genodeftest ja soweit alles erklärt.

Außerdem hast du einen gravierenden Fehler gemacht. Du vergleichst Sprachen und stellst sie auf die gleiche Stufe, was sie aber nicht sind. Jede Sprache hat ihre eigene Philosophie und entsprechend sind dann auch die Vor- bzw. Nachteile gegenüber anderen Sprachen vertreten. Man kann nicht einfach eine Sprache lernen und dann versuchen in einer anderen zu programmieren, ohne sich die Philosophie dieser anzueignen, dabei kommt nur Müll bei rum. Wenn du Java nutzen willst, dann lern Java richtig und vergiss in dem Moment alle anderen Sprachen, die du jemals benutzt hast.

EDIT:
Natürlich darf man auch nicht die Geschichte einer Sprache vergessen. Und wenn ich mir mal so überlege, was C und C++ im Laufe ihrer Existenz alles durchlebt und mitgemacht haben und noch immer weit davon entfernt sind perfekt zu sein bzw. wie viel Müll und Altlasten noch immer mitgeschleppt werden, um halbwegs abwärtskompatibel zu sein, dann kann man vielleicht verstehen, dass es Java da auch nicht viel anders geht.
 
Zuletzt bearbeitet: