Warum ich Java hasse

Developer-Tools, Entwicklungsumgebungen und alles andere, was sich installieren lässt
Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Warum ich Java hasse

Beitrag von fat-lobyte » Mo Sep 29, 2014 10:59 am

Hallo, dies ist ein dezidierter Java-Flame-Thread. Wenn das unerwünscht ist, bitte sofort schließen/löschen.
-------------
Früher war mein Java-Hass auf ein paar Vorurteilen und einigen theoretischen Überlegungen begründet, aber nachdem ich nun an einem Java Projekt arbeite hat sich meine Abneigung konkretisiert. Betrachtet dazu folgende C++/Java-Programme.

Das Beispiel mag im ersten Moment künstlich aussehen, aber die Grundaufgabe ist eine Reale und besteht darin aus einer Serie von Objekten gewisse Statistiken auszurechnen.

Hier die C++-Version:

Code: Alles auswählen

#include <iostream>

#include <vector>
#include <string>
#include <map>

struct Datapoint {
	const std::string wetter;
	const unsigned niederschlag;
};

std::vector<Datapoint> tage{
	{"Regen", 4}, {"Wolken", 33}, {"Schnee", 6}, {"Schnee", 4}, 
	{"Sonne", 12}, {"Regen", 4}, {"Nebel", 0},
	{"Wolken", 16},
	{"Nebel", 19}, {"Schnee", 4}, {"Wolken", 14},
	{"Schnee", 5}
};

int main()
{
	std::map<std::string, std::pair<unsigned short, unsigned short>> counters;
	
	for (auto datapoint : tage)
	{
		if (!counters.count(datapoint.wetter))
			counters[datapoint.wetter] = std::make_pair(0u, 0u);
		
		if (datapoint.niederschlag <= 12)
			++counters[datapoint.wetter].first;
		else
			++counters[datapoint.wetter].second;
	}
	
	for (auto tagwetter : counters)
	{
		std::cout<<"An "<<tagwetter.first<<"tagen gab es "<<
			tagwetter.second.first<<" mal wenig Niederschlag und "<<
			tagwetter.second.second<<" mal viel Niederschlag.\n";
			
	}
		
	return 0;
}
Hier die Java-Version mit meinen Kommentaren:

Code: Alles auswählen

import java.util.*;
import java.util.Map.Entry;

import javafx.util.Pair;


class Maps {

    static class Datapoint {
        final String wetter; // final ist nicht const!!!
        final int niederschlag; // kein unsigned? Schade :(
        
        // default konstruktor explizit. Muss das sein? Ist
        // das für den Compiler echt so schwierig?
        public Datapoint(String wetter, int niederschlag) 
        {
            this.wetter = wetter;
            this.niederschlag = niederschlag;
        }
    }
    
    static List<Datapoint> tage = new ArrayList<>(); // nicht im Konstruktor initialisierbar? Schade :(
    static { // wo sind wir denn hier gelandet?
      //Initializer Blocks sehen aus wie ne Krücke für fehlende Konstruktorinitialisierungen
    
        tage.addAll(Arrays.asList( // addAll(asList(...)) ???
            new Datapoint("Regen", 4), new Datapoint("Wolken", 33), 
            new Datapoint("Schnee", 6), new Datapoint("Schnee", 4), 
            new Datapoint("Sonne", 12), new Datapoint("Regen", 4), new Datapoint("Nebel", 0)
        ));
        
        // oder doch lieber so?
        tage.add(new Datapoint("Wolken", 16));
        tage.add(new Datapoint("Nebel", 19));
        tage.add(new Datapoint("Schnee", 4));
        tage.add(new Datapoint("Wolken", 14));
        tage.add(new Datapoint("Schnee", 5));
        
        
        // new, new, new, new, new, .... Wisst ihr eigentlich was das für die
        // Speicherfragmentierung bedeutet? 
    }

    public static void main(String [] args)
    {
        
        Map<String, javafx.util.Pair<Integer, Integer>> counters = new HashMap<>();
        // javafx.util.Pair? gibts nichtmal eine Pair klasse in der "Haupt"-Java-distribution?
        
        // Um in eine "Collection" reinzugehen müssen die werte vom typ "Object"
        // abgeleitet sein (C++-Äquivalent: void* ). Dazu kann man also nicht einmal "int" verwenden,
        // sondern nur die Integer-Klasse.
    
    
        for (Datapoint datapoint : tage)
        {
            javafx.util.Pair<Integer, Integer> pair = counters.get(datapoint.wetter);
            if (pair == null)
            {
                pair = new javafx.util.Pair<Integer, Integer>(new Integer(0), new Integer(0));
                // new, new, new. Hübsch, oder?
            }
            
            // wir können ein Integer-Objekt in einem Pair nicht inkrementieren.
            // Deswegen vorher extra abspeichern!
            Integer k = pair.getKey(), v = pair.getValue();
            
            if (datapoint.niederschlag <= 12)
            {
                // wir können das Integer in dem Pair nicht einfach ersetzen.
                // Deswegen ein neues Pair erstellen!
                pair = new javafx.util.Pair<Integer, Integer>(k + 1, v);
            }
            else
            {
                pair = new javafx.util.Pair<Integer, Integer>(k, v + 1);
            }            
            
            counters.put(datapoint.wetter, pair);
        }
        
        
        for (Entry<String, Pair<Integer, Integer>> tagwetter : counters.entrySet())
            // Entry<String, Pair<Integer, Integer>>...blablala. Warum nicht einfach auto?
        {
            System.out.println("An "  + tagwetter.getKey() + "tagen gab es " +
                tagwetter.getValue().getKey() + " mal wenig Niederschlag und " +
                tagwetter.getValue().getValue() + " mal viel Niederschlag.");
        }
    }
}
Unter anderem deswegen glaube ich, dass Java im Vergleich zu C++ eine absolut schlechtere Sprache in fast allen Anwendungsgebieten ist. Ihr könnt mir gerne Wiedersprechen oder noch was draufpacken. Aber achtung, dies ist ein rein emotionaler Thread!
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Warum ich Java hasse

Beitrag von Xin » Mo Sep 29, 2014 4:45 pm

Willkommen daheim. ^^

Ich habe Java übrigens hassen gelernt, als ich ein C++ 3 Zeiler auf drei Bildschirmseiten Java-Code portiert habe - und ich hatte damals schon zu Röhrenzeiten die 1600x1200 als Bildschirmauflösung. Eine Bildschirmseite war also ausreichend Text. ^^
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Warum ich Java hasse

Beitrag von nufan » Mo Sep 29, 2014 5:03 pm

Das nächste mal bitte die Suche verwenden, dazu gibts schon einen Thread :D
http://www.proggen.org/forum/viewtopic.php?f=22&t=1337

nouseforname
Beiträge: 236
Registriert: Do Feb 10, 2011 6:31 pm

Re: Warum ich Java hasse

Beitrag von nouseforname » Mo Sep 29, 2014 5:26 pm

Ihr seid schlimm.... Java ist toll^^ Ich muss das sagen, allein schon wegen Android ;)

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Warum ich Java hasse

Beitrag von Xin » Mo Sep 29, 2014 5:34 pm

nufan hat geschrieben:Das nächste mal bitte die Suche verwenden, dazu gibts schon einen Thread :D
http://www.proggen.org/forum/viewtopic.php?f=22&t=1337
Hehehe, jawohl, Herr Moderator ;-)

Wobei ich den aber schön finde wegen der ganzen Kommentare. ^^
Auch wenn sich der Kommentar für das überflüssige new wiederholt. :-D
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Warum ich Java hasse

Beitrag von fat-lobyte » Di Sep 30, 2014 9:07 am

nufan hat geschrieben:Das nächste mal bitte die Suche verwenden, dazu gibts schon einen Thread :D
http://www.proggen.org/forum/viewtopic.php?f=22&t=1337
Jawohl, Herr Moderator.

Xin hat geschrieben:Wobei ich den aber schön finde wegen der ganzen Kommentare. ^^
Auch wenn sich der Kommentar für das überflüssige new wiederholt. :-D
Es tut ja auch ganz besonders weh ;)

Aber mal im ernst: " new Pair<Integer, Integer>(new Integer(0), new Integer(0))"??? Muss das sein?
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Warum ich Java hasse

Beitrag von cloidnerux » Di Sep 30, 2014 9:14 am

Aber mal im ernst: " new Pair<Integer, Integer>(new Integer(0), new Integer(0))"??? Muss das sein?
"Ja das muss!"
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
oenone
Beiträge: 223
Registriert: Do Sep 01, 2011 2:42 pm
Wohnort: Bremen
Kontaktdaten:

Re: Warum ich Java hasse

Beitrag von oenone » Di Sep 30, 2014 1:16 pm

Du solltest dich auch nicht zu sehr auf eine 1:1-Übersetzung versteifen. Warum meinst du z.B. const zu brauchen? Oder eine eigene Klasse für die Datenpunkte?

Du kannst sehr wohl eine Liste im Konstruktor bzw. bei der Deklaration initialisieren.

Code: Alles auswählen

ArrayList<Foo> Bar = new ArrayList<Foo>() {{ add("a"); add("b"); ... }}
Anstelle von javafx würde ich lieber eine mutable Pair-Klasse selbst erstellen. Das reduziert einiges. Java und C++ haben halt unterschiedliche Standard-Klassenbibliotheken. C++ hat auch einiges nicht, was in Java standard ist. Genauso könnte man ein Beispiel konstruieren, das in Java drei und in C++ dreißig Zeilen benötigt.

Wenn du wirklich Java machen willst (oder eine andere managed Sprache), musst du dich wohl an die vielen news gewöhnen. Das hat auch nicht unbedingt etwas mit Speicherfragmentierung zu tun.

Ich selbst mag Java auch nicht besonders und einiges ist durchaus berechtigt (z.B. Integer vs int). Vieles ist aber einfach eine andere Herangehensweise und Gewöhnungssache.

PS: Das auto-Keyword gibt es in C++ auch noch nicht so lange :-P

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Warum ich Java hasse

Beitrag von fat-lobyte » Do Okt 02, 2014 2:41 pm

oenone hat geschrieben:Du solltest dich auch nicht zu sehr auf eine 1:1-Übersetzung versteifen.
Prinzipiell völlig richtig. Das beispiel kommt aber aus der Praxis: ich wollte eine Aufgabe lösen und habe den einfachsten Weg gesucht, bin über all diese Stolpersteine gestolpert und bin Nachträglich draufgekommen wie einfach das mit C++ gewesen wäre.
oenone hat geschrieben:Warum meinst du z.B. const zu brauchen?
Hier brauche ich das gar nicht. Wo ich es aber unglaublich gerne hätte sind Methodenparameter. Ich würde gerne in der Methodendeklaration garantieren, dass bei der Übergabe eines Objektes dieses nicht verändert wird. Klar kann ichs in die Doku schreiben "object is not modified" und dann in der Methode "brav" sein, aber das nicht nicht das gleiche wie ein C++-const. Das ist felsenfest, und auf das kann ich mich verlassen.
oenone hat geschrieben:Oder eine eigene Klasse für die Datenpunkte?
Das kommt aus der realen Aufgabe heraus. Die "Datenpunkte" sind in wirklichkeit eine Serie von Objekten die aus einer speziellen Datenbank kommen.
oenone hat geschrieben:Du kannst sehr wohl eine Liste im Konstruktor bzw. bei der Deklaration initialisieren.

Code: Alles auswählen

ArrayList<Foo> Bar = new ArrayList<Foo>() {{ add("a"); add("b"); ... }}
Moment, das ist aber nicht das gleiche! Hier erstellst du eine lokale, anonyme, von ArrayList abgeleitete Klasse! Ich finde das persönlich ganz und gar nicht schön. Denn
1) im Endeffekt ist dort erst wieder ein initializer-Block am Werk (wie bei meinem Code),
2) ArrayList implementiert Serializable; das bedeutet, ich muss auch in dieser anonymen Klasse serialVersionUID deklarieren wenn ich ohne Warnungen auskommen will
3) Beim Debuggen sehe ich den Typ von Bar als Klasse$Anonymous1 oder irgend so einen Blödsinn, anstatt klip und klar ArrayList.

Der C++-Initializer tut hier etwas völlig anderes: er erstellt Objekte lokal am Stack, allokiert dann innerhalb der Map/Liste/Vector den speicher, und "verschiebt" dann die Objekte mithilfe des Move-Constructors Foo(Foo&& foo) die Objekte in den allokierten Bereich (was meistens "keinen" Kopieraufwand bedeutet). Oder nicht. Ich habe keine Ahnung von C++ mehr :D. Es ist auf jeden Fall um einiges effektiver und schöner.
oenone hat geschrieben:Anstelle von javafx würde ich lieber eine mutable Pair-Klasse selbst erstellen. Das reduziert einiges. Java und C++ haben halt unterschiedliche Standard-Klassenbibliotheken.
Das stimmt, und im Endeffekt habe ich das auch so gelöst:

Code: Alles auswählen

    public static class IntegerPair
    {
        public int first;
        public int second;
        
        public IntegerPair(int first, int second)
        {
            this.first = first;
            this.second = second;
        }
    }
Funktioniert eh. Aber meine Frage: WARUM muss ich das machen? Ist ein "Pair" (oder ein Tuple, wenn wir schon dabei sind) wirklich so eine Exotische Datenstruktur? Wie gesagt: nachbauen kann ich mir alles, aber wenn solche Dinge nicht in der Sprache vorhanden sind dann ist das erstmal ein Stolperstein.
oenone hat geschrieben:C++ hat auch einiges nicht, was in Java standard ist. Genauso könnte man ein Beispiel konstruieren, das in Java drei und in C++ dreißig Zeilen benötigt.
Mag sein, aber das ist nicht Symmetrisch. Ich glaube dass meistens ein C++-Programm kürzer ausfällt. Aber wieso machen wir nicht einen kleinen Wettbewerb daraus? Finde eine Problem, wo der Java-Code kürzer ist als der C++-Code. Dazu eine Einschränkung: alles was du aus der Java API importierst, darf ich funktionell durch Boost oder andere Bibliotheken/Frameworks ersetzen. Deal?

Übrigens zieht C++ mit C++14 und C++17 mit den ganzen Standardbibliotheken ebenfalls langsam nach.
Wenn du wirklich Java machen willst (oder eine andere managed Sprache), musst du dich wohl an die vielen news gewöhnen. Das hat auch nicht unbedingt etwas mit Speicherfragmentierung zu tun.

Ich selbst mag Java auch nicht besonders und einiges ist durchaus berechtigt (z.B. Integer vs int). Vieles ist aber einfach eine andere Herangehensweise und Gewöhnungssache.
Richtig. Ich habe im Beispielcode auch bewusst einige Eigenheiten nicht angesprochen um Polemik zu vermeiden. Gewöhnen kann ich mich an fast alles, aber an umso mehr Eigenheiten/Überraschungen ich mich gewöhnen und akzeptieren muss, umso weniger mag ich die Sprache und umso weniger empfinde ich sie als "schön".

PS: Das auto-Keyword gibt es in C++ auch noch nicht so lange :-P
3 Jahre, und in allen Compilern mit dabei. ;) Die "Theorie" dahinter steht auch schon länger, also wieso noch nicht in Java?
Haters gonna hate, potatoes gonna potate.

hermi
Beiträge: 3
Registriert: Do Dez 04, 2014 2:49 am

Re: Warum ich Java hasse

Beitrag von hermi » Do Dez 04, 2014 8:37 am

Warum denn, ich benutze gern Java.
1.Java ist einfach, leicht zu erlernen als C \ C ++
2.Java ist vollständig objektorientiert , wie Arrays in Java ist eine Aufgabe der Länge dieses Attribut enthalten, im Gegensatz zu C ++ ist ein Array einen Zeiger. So besuchen Sie Arrays, wird Java ausführen Abgrenzungsüberprüfung, sicherer, aber auf Kosten der Geschwindigkeit. Und wegen all der Java Object-Klasse wird diese Basisklasse erben, so können Sie ein paar gute unabhängige Klassen mit der Basisklasse verbunden sind, wie beispielsweise in einem Array setzen.
3.Mit Java gibt es kein Zeiger so unsicher (obwohl die Zeigergeschwindigkeit) Konzept.
4.Java hat die Speicherverwaltung, Müllabfuhr automatisch verbessert, wodurch die maximal mögliche Speicherüberlauf kann auch die Programmierung Effizienz zu verbessern.
5.Java ist in einer perfekten Ausnahmemechanismus (C ++ Standard ist nicht perfekt).
6.java Datenobjekt sich in dem Haufen zu erhalten, während auf dem Stapel durch einen Handgriff mit diesem verbunden. Dieses Design ist mehr zumutbar ist.
Java kann aus den oben genannten Punkte und sicherer zu erkennen.
Vollständige Multi 8.Java Standardbibliothek, im Vergleich zu C ++ zusätzlich zu einem STL (sondern auch super schwer zu handhaben) weg ist, tatsächlich erfordert eine Menge Programmierung in C ++ mit 3rd-Party-Bibliotheken. Dies ist vor allem, weil es eine Reihe von Unternehmen der gewerblichen Wirtschaft, um Java-Update Geschwindigkeit unterstützt, und C ++ Normenausschuss ist nur ein armer, auf einer C ++ Standard-Version oder C ++ 98. .
9. Java, da das Programm den Byte-Code benötigt, um die JVM-Bytecode ausführen kompiliert und dann in Maschinencode übersetzt, so dass er plattformübergreifende, einmal kompiliert, laufen überall. Aber es ist auch die Hauptursache für ihn verlangsamen.
10.Java native Unterstützung für Multi-Threading (C ++ Standardbibliothek allein kann das nicht), native UI wie AWT Swi

Antworten