String equals null wird nicht angenommen.

Status
Nicht offen für weitere Antworten.

fuerchterBR

Mitglied
Hallo liebe Leute,
mein erster Post und auch schon direkt eine Frage.
Und zwar bin ich im moment ein klein wenig mit den Java-Basics am rumexperimentieren, und ich stehe momentan vor einem problem.
Und zwar habe ich im Verlauf meines Quelltextes die Variable egoeins (egozwei, egodrei,...), aus denen ich etwas schließen will, wenn die Variablen leer sind, dafür habe ich dann angenommen, egoeins (egozwei etc.) sei "null". Allerdings, wenn ich meinen Code so anwende, wie ich ihn hierunter posten werde, erhalte ich beim ausführen des Projekts eine Fehlermeldung.

Java:
import java.io.*;

/**
 * Write a description of class Text here.
 * 
 * @author fuerchterBR
 * @version 09-15-09 v0.001
 */
public class Text
{
    // instance variables - replace the example below with your own
public int leben;
public String eingabe;
public String name;
public String erzaehler;
public String antwortja;
public String antwortnein;
public String egoeins;
public String egozwei;
public String egodrei;
public String egovier;
public String egofuenf;
public String egosechs;
public String egosieben;
public String egoacht;
public String egoneun;
public String egozehn;
public String antworteins;
public String antwortzwei;
public String antwortdrei;
public String antwortvier;
public String antwortfuenf;
public String antwortsechs;
public String antwortsieben;
public String antwortacht;
public String antwortneun;
public String antwortzehn;
    /**
     * Constructor for objects of class Text
     */
    public Text()
    {
        startespiel();
     }
     //methoden
     //methode um das Spiel zu starten.
     public void startespiel(){
        leben=100;
        erzaehler="Sie wachen auf und sehen eine Kerze, die neben ihrem Bett steht.";
        erzaehlen();
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        erzaehler="/Wollen sie sie auspusten?";
        erzaehlen();
        antwortja="Sie pusten die Kerze aus und schlafen erneut ein. Das Spiel wird neu gestartet.";
        antwortnein="/Geben sie ihren Namen ein.";
        abfragejanein();
        abfragename();
        erzaehler="Herzlich Willkommen in diesem Textadventure, "+name;
        erzaehlen();
        erzaehler="Lasst uns die Geschichte weiter verfolgen!";
        erzaehlen();
        erzaehler="Sie stehen auf und bemerken die bäuerliche, aber auch mittelalterliche Dekoration, als ein Ritter das Zimmer betritt.";
        erzaehlen();
        erzaehler="'Steh auf und beweg dich, "+name;
        erzaehlen2();
        erzaehler="du dummer Alter Bauer!'";
        erzaehlen();
        erzaehler="/Antworten sie dem Ritter!";
        erzaehlen();
        erzaehler="Antwortmöglichkeiten:";
        erzaehlen2();
        erzaehler="____________________";
        erzaehlen2();
        erzaehler="1) Jawohl, mein Herr, ich bin bereit erneut zu dienen!";
        erzaehlen2();
        erzaehler="2) Jaja, ich komme ja schon, was mache ich hier überhaupt, und wieso werde ich als Bauer beschimpft?";
        erzaehlen2();
        erzaehler="3) Niemals, ich bleibe liegen, ich werde nicht für ein solch eitles Königreich dienen!";
        erzaehlen2();
        egoeins="Jawohl, mein Herr, ich bin bereit erneut zu dienen!";
        egozwei="Jaja, ich komme ja schon, was mache ich hier überhaupt, und wieso werde ich als Bauer beschimpft?";
        egodrei="Niemals, ich bleibe liegen, ich werde nicht für ein solch eitles Königreich dienen!";
        antworteins="'Komm mit mir!', sagt der Ritter.";
        antwortzwei="'Ich beschimpfe dich als Bauer, weil du einer bist, und jetzt komm!', sagt der Ritter.";
        antwortdrei="'Na gut, dann bleibst du halt liegen, dem König wird das garantiert nicht gefallen, wenn ich es ihm berichte!', sagt der Ritter.";
        abfrageeinszehn();
    }
     //erzaehlen-methode, die die Variable erzaehler in der console wiedergibt.
     public void erzaehlen(){
     System.out.println(""+erzaehler);
     try{
        Thread.sleep(4000);
     }
     catch (InterruptedException e){
     }
    }
     //erzaehlen-methode, die die Variable erzaehler in der console wiedergibt. (Ohne Pause)
     public void erzaehlen2(){
     System.out.println(""+erzaehler);
    }
     //ja/nein-abfrage mit vorher zu definierender Antwort.
     public void abfragejanein(){
         try{
            BufferedReader in = new BufferedReader(
            new InputStreamReader( System.in ) );
            eingabe = in.readLine();
        }
        catch(IOException ex ){
        System.out.println( ex.getMessage() );
    }
    if (eingabe.equals("Ja")){
        System.out.println(""+antwortja);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        startespiel();
    }
        
    else if (eingabe.equals("Nein")){
        System.out.println(""+antwortnein);
    }
    else{
            System.out.println("Falsche Eingabe!");
            abfragejanein();
        }
    }
    
    //abfrage die eine beliebige Eingabe erfordert.
     public void abfrage(){
         try{
            BufferedReader in = new BufferedReader(
            new InputStreamReader( System.in ) );
            eingabe = in.readLine();
        }
        catch(IOException ex ){
        System.out.println( ex.getMessage() );
    }
}
    //abfrage die den Namen erfordert.
     public void abfragename(){
         try{
            BufferedReader in = new BufferedReader(
            new InputStreamReader( System.in ) );
            name = in.readLine();
        }
        catch(IOException ex ){
        System.out.println( ex.getMessage() );
    }
}

    //abfrage die eine Antwort von 1-10 erwartet
     public void abfrageeinszehn(){
        try{
            BufferedReader in = new BufferedReader(
            new InputStreamReader( System.in ) );
            eingabe = in.readLine();
        }
        catch(IOException ex ){
        System.out.println( ex.getMessage() );
    }
    if (eingabe.equals("1")){
        System.out.println("-"+egoeins);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antworteins);
    }
        
    else if (eingabe.equals("2")){
        System.out.println("-"+egozwei);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortzwei);
    }
    else if (eingabe.equals("3")){
        System.out.println("-"+egodrei);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortdrei);
    }
    else if (eingabe.equals("4")){
        System.out.println("-"+egovier);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortvier);
    }
    else if (eingabe.equals("5")){
        System.out.println("-"+egofuenf);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortfuenf);
    }
    else if (eingabe.equals("6")){
        System.out.println("-"+egosechs);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortsechs);
    }
    else if (eingabe.equals("7")){
        System.out.println("-"+egosieben);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortsieben);
    }
    else if (eingabe.equals("8")){
        System.out.println("-"+egoacht);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortacht);
    }
    else if (eingabe.equals("9")){
        System.out.println("-"+egoneun);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortneun);
    }
    else if (eingabe.equals("10")){
        System.out.println("-"+egozehn);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortzehn);
    }
    else{
        System.out.println("Falsche Eingabe!");
        abfrageeinszehn();
        }
/**    if (egovier.equals("null")){
        System.out.println("Falsche Eingabe!");
        abfrageeinszehn();
    }   */
}
}

Wenn ich nun also an dem Punkt bin, an dem die Nummer zwischen 1 und 10 (egoeins-egozehn) abgefragt wird und ich die 4 (die nicht definiert ist, also "null" sein müsste), erhalte ich folgende Meldung (der Code, der die Problemstelle darstellt ist als comment im Quelltext ganz unten angehangen):
NullPointerException:
null

mfg fuerchterBR

//EDIT:
Und ja, falls die Frage kommen sollte, ich habe gegoogelt, aber die Ergebnisse waren entweder so formuliert, dass ich sie nicht verstehen konnte, oder sie behandelten nicht das richtige Problem.

//EDIT2:
Falls es helfen sollte, ich habe auch bereits probiert
Java:
if (egovier.equals(""))
zu schreiben, selbes Problem.
 
Zuletzt bearbeitet:

Landei

Top Contributor
Wenn du irgend eine Methode an einer Referenz aufrufst, die gerade null ist, gibt es eine NPE

Java:
String x = "bla";
String y = null;
if(x.equals(y)) {} //<--OK
if(y.equals(x)) {} //<-- Boom!!!!
if(y != null && y.equals(x)) {} // <-- Ist immer sicher
if("irgendeineStringKonstante".equals(y)){} //Auch immer sicher

Das war ja genau der Grund, warum in Java7 die Null-sicheren Operatoren( ?. und ?: , a.k.a. "Elvis") eingeführt werden sollten (was sie inzwischen aber unverständlicherweise wieder rausgeschmissen haben)
 

Sanix

Top Contributor
Wenn ein Objekt, in diesem FAll dein String null ist, kannst du keine Methoden davon aufrufen. Da das Objekt nicht existiert. Wenn du es auf null prüfen willst musst du
[c]egovier == null[/c] prüfen. Dies bedeutet, dass kein String referenziert ist, was wohl in deinem Fall zutrifft.
 
M

maki

Gast
[c]null[/c] ist eine Null-Referenz, [c]"null"[/c] dagegen ist ein String.
Wenn du versuchst eine Null-Referenz zu dereferenzieren (zB.[c]null.irgendEineMethode()[/c]), gibt es eine NullPointerException.
Man kann sich einen Nullcheck sparen, indem man zB. die für null in Frage kommende Refrenz nicht dereferenziert: [c]"einString".equals(eineMöglicheNullReferenz)[/c]
Aber was du wohl brauchst sieht eher so aus: [c]if (null == egovier)[/c]

Respekt für den Mut solchen Code zu posten :)
 

fuerchterBR

Mitglied
Also muss ich egovier etc. extra definieren auf "nichts" oder ähnliches um dies abzufragen?

btw. danke für die schnelle Antwort.
 

Landei

Top Contributor
Eine Referenz kann auf "gar nichts" zeigen. "Gar nichts" ist etwas ganz anderes, als ein leerer String (der immer noch ein String ist) und heißt in Java null (ohne Anführungszeichen). Es hat keine Methoden, die man aufrufen könnte, es fliegt einem immer um die Ohren. Bevor man etwas mit einer Referenz tut, die eventuell null ist, muss man das halt vorher testen (wie vom Vorredner beschrieben).

Null ist eine der dümmsten Ideen überhaupt in der IT (der "Erfinder" T. Hoare bezeichnete sie als seinen "Milliarden-Dollar-Fehler"), aber wir müssen in Java leider damit leben.
 
S

Spacerat

Gast
...was du wohl brauchst sieht eher so aus: [c]if (null == egovier)[/c]
Öhm... Ich würd'
Java:
if(egovier.equals("")) {
schlicht durch
Java:
if("".equals(egovier)) {
ersetzen (hat maki ja auch schon angedeutet). Und niemals vergessen:
Java:
definedObject.equals(undefinedObject);
Respekt für den Mut solchen Code zu posten :)
Dem schliess' ich mich an.
 
Zuletzt bearbeitet von einem Moderator:

fuerchterBR

Mitglied
Okay, danke es funktioniert, ich habe aber dafür eine kleine Änderung gemacht, damit es funktioniert bzw. um den Code einfacher zu gestalten.

Java:
    else if (eingabe.equals("4") & "".equals(egovier)){
        System.out.println("-"+egovier);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortvier);
    }

Wenn ich das nicht in die else if Bedingung reingeschrieben hätte, hätte er mir "-null" und "null" geprintet. :D
Naja, danke auf jedenfall, hat mir sehr geholfen.

mfg fuerchterBR

//EDIT:
Ja, das ganze so in die einzelnen else if prozesse reinzuschreiben, wie ich es oben im Code schon gemacht habe (am Beispiel von egovier) lässt alle Antworten (1-10) die Antwort "Falsche Eingabe" bringen. Daraufhin ist mir aufgefallen, dass die Abfrage ja eigentlich sein muss "wenn die eingabe 1 ist und egoeins nicht null ist, dann gebe text aus". Naja, daraufhin noch einmal gegoogelt und den Code umgeändert in:

Java:
    else if (eingabe.equals("4") & !"".equals(egovier)){
        System.out.println("-"+egovier);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortvier);
    }

Leider auch nicht erfolgreich, habe ich mich verlesen, oder stimmt das Ungleich mit dem Ausrufezeichen? Jedenfalls gibt mir die Konsole erneut die Antworten "-null" und "null", da ja nichts definiert ist (Es sollte eig. "Falsche Eingabe" (wie im else) kommen und das Eingabefeld wiederholt werden).

//EDIT2:

Habe jetzt einmal makis version probiert:

Java:
    else if (eingabe.equals("4") & null != egovier){
        System.out.println("-"+egovier);
        try{
            Thread.sleep(4000);
        }
        catch (InterruptedException e){
        }
        System.out.println(""+antwortvier);
    }

Für egovier funktioniert diese Variante schon einmal, nun noch schnell bei dem Rest ausprobieren. Ok danke, funktioniert super, ich denke man kann das Thema jetzt schließen, habe vorerst keine weiteren Probleme.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
Null ist eine der dümmsten Ideen überhaupt in der IT (der "Erfinder" T. Hoare bezeichnete sie als seinen "Milliarden-Dollar-Fehler"), aber wir müssen in Java leider damit leben.
stimmt nicht, falls sich irgendjemand beeinflussen lassen sollte,
in der ernsthaften Diskussion darüber blieben fragliche Punkte von Landei unbeantwortet,
etwa
http://www.java-forum.org/allgemeine-java-themen/87667-java-7-auslese-3.html#post552931

ohne null wäre ein sinnvolles Programm nicht denkbar, von kleinen Code-Schnipseln und generell anderen Programmierstil (funktional) abgesehen
 
Zuletzt bearbeitet von einem Moderator:

Landei

Top Contributor
@fuerchterBR: Auch wenn es funktionert, bitte in Tests nicht & sondern && nehmen, weil das die rechte Seite nur dann auswertet, wenn es "nötig" ist
Java:
String s = null;
if(s != null & s.length() > 4) {} //BUMM!!!
if(s != null && s.length() > 4) {} //OK

stimmt nicht, falls sich irgendjemand beeinflussen lassen sollte,
in der ernsthaften Diskussion darüber blieben fragliche Punkte von Landei unbeantwortet,
etwa
http://www.java-forum.org/allgemeine-java-themen/87667-java-7-auslese-3.html#post552931

ohne null wäre ein sinnvolles Programm nicht denkbar, von kleinen Code-Schnipseln und generell anderen Programmierstil (funktional) abgesehen

Ich bleibe bei meiner Meinung. Das Haskell usw. ohne null auskommen, liegt nicht am "funktionalen" Stil, denn wie man sieht, lässt sich die Option-Lösung ohne weiteres auf OO-Sprachen übertragen, es gibt aber auch andere Ansätze (Wikipedia nennt "Void safety, or static protection against calls on null references, through the attached-types mechanism." als Eigenschaft von Eiffel). Elvis-Operatoren u.s.w in vielen Sprachen (leider nicht in Java7) bekämpfen zwar nur die Symptome, zeigen aber, dass da etwas prinzipiell schiefläuft. Auch Sprachdesigner sind da meiner Meinung, etwa Bertrand Meyer: http://docs.eiffel.com/sites/default/files/void-safe-eiffel.pdf . Bei der Entwicklung neuerer Sprachen wird laut darüber nachgedacht, wie man null loswerden oder die Effekte zumindest eindämmen kann (in Fan kann man z.B. angeben, dass bestimmte Variablen oder Argumente nicht null sein dürfen).

Im übrigen ist es kein Problem, dass eine Variable zunächst "undefiniert" ist, solange der Compiler nachweisen kann, dass der erste Zugriff auf die Variable immer eine Zuweisung ist. Das ist insbesondere nützlich, wenn die Sprache eine "lazy"-Semantik unterstützt, also das Lazy Initialization Pattern ein Sprachbestandteil wird (womit viele Probleme mit der Initialisierungsreihenfolge wegfallen, wofür man sonst null benötigen würde).

Null ist ein Krebsgeschwür, es ist ein Konzept, das mit Objektorientierung nicht vereinbar ist, denn die Kernaussage eines guten OO-Systems ist "Alles ist ein Objekt". Null ist ein Sonderfall, der überall berücksichtigt werden muss. Null ist eine Zeitbombe, die man hier in ein System wirft, und die einen halben Tag später dort mit einer NPE hochgeht. Mit einer leeren Liste einm Array der Länge 0 oder dem leeren String hat man keine Probleme, es sind Objekte und verhalten sich auch wie Objekte. Soll ich bei einer Suche, bei der nichts gefunden wurde, null zurückgeben? Sicher nicht, denn eine leere Liste drückt viel besser das Ergebnis der Suche aus, und eine nachfolgende for-Schleife ist überhaupt kein Problem. Warum soll das für andere Typen nicht auch gelten?
 

faetzminator

Gesperrter Benutzer
Dann nehmen wir als Beispiel einen Point. Soll er - falls "null" - x und y als 0,0 beschreiben? oder MIN_VALUE? In allen Fällen könnte der Wert auch vom Benutzer gesetzt sein. Man kann natürlich auch einen boolean hinzufügen, der bestimmt, ob der Point "null" ist. Aber da kann ich gleich gegen null checken!?
 
B

bygones

Gast
Natuerlich hat man bei ValueObjects (z.b. Point) immer eine Diskussion zwischen ungueltigen Zustand und bewusstem Zustand. D.h. ist Point(0,0) etwas anderes als ein ungueltiger Punkt. Ich wage zu behaupten dass dies nicht generell zu loesen ist sondern eben von Fall zu Fall zu unterscheiden ob in einer Applikation man 0 oder MIN/MAX Value nutzt

ansonsten auch siehe: Effective Java Item 43

Dennoch bin ich und bleibe ich ein absoluter Gegner von null.... is satan sozusagen ;-)
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
Das Haskell usw. ohne null auskommen [..]
mit solch allgemeinen Aussagen kann ich leider nichts anfangen,
ich weiß nicht wie in Haskell ein JFrame oder 1000 andere Klasse mit 10.000 Klassenattributen definiert ist,

ob für jede Klasse manuell ein eigenes Null-Objekt definiert ist usw.
Bei der Entwicklung neuerer Sprachen wird laut darüber nachgedacht, wie man null loswerden oder die Effekte zumindest eindämmen kann (in Fan kann man z.B. angeben, dass bestimmte Variablen oder Argumente nicht null sein dürfen).
ähm, ja, genau wie in Java: if (x == null) { throw Exception(); }

kürzere Syntax ist bisschen was anderes als 'null existiert nicht'?

falls der Compiler das automatisch beim Aufrufer prüft wäre man fast wieder bei
'Variable darf man nicht null zuweisen'

das ist natürlich interessantes Konzept, bisher konntest du dich zu diesem Punkt noch nicht durchdringen

Im übrigen ist es kein Problem, dass eine Variable zunächst "undefiniert" ist, solange der Compiler nachweisen kann, dass der erste Zugriff auf die Variable immer eine Zuweisung ist.
ok, da stehts ja doch,
und da ist wie gesagt meine Frage: zwingt einen eine solche Sprache, zu allen Klassen ein Null-Objekt anzulegen?
oder anderenfalls immer eine Exception zu werfen falls etwas nicht initialisiert wurde?
Null ist eine Zeitbombe, die man hier in ein System wirft, und die einen halben Tag später dort mit einer NPE hochgeht.
über etwas zu meckern ist leicht, aber ohne eine Alternative aufzuzeigen?
ich sehe keine andere Möglichkeit bzw. ich verweise auf diverse andere Probleme, die versteckte Standardwerte zur Folge haben

Soll ich bei einer Suche, bei der nichts gefunden wurde, null zurückgeben? Sicher nicht, denn eine leere Liste drückt viel besser das Ergebnis der Suche aus, und eine nachfolgende for-Schleife ist überhaupt kein Problem. Warum soll das für andere Typen nicht auch gelten?
Container haben eine einfache feste Semantik,
ist leer? ja/ nein
get/ set/ iterate

selbst das wäre übrigens automatisch erstellt für einen Computer wohl nicht sinnvoll zu lösen sein,
der würde bei Standard-Rückgabewerten bei isEmpty() false zurückgeben und bei isNotEmpty() genauso -> Chaos

man muss also manuell eigene NULL-Objekte definieren,
und das ist ja schon länger meine Frage: zwingt die Sprache den Programmierer wirklich, zu jeder Klasse ein NULL-Objekt zu definieren?
für sich schon ungeheuerlich,
aber wenn, dann habe ich glaube ich noch paar weitere Punkte auf Lager,

ohne NULL-Objekt sehe ich noch weniger durch, wie das alles funktionieren soll

@faetzminator
> Aber da kann ich gleich gegen null checken!?

nur dann wenn man muss, siehe EMPTY_LIST und Iterator, es gibt Fälle, in denen NULL-Objekte ganz natürlich ohne Check verwendet werden können,
nur nicht immer, ein Gegenbeispiel spricht nicht gegen das Pattern
aber es spricht dagegen, null in einer Sprache zu verbieten
 
B

bygones

Gast
ich hab so das Gefuehl NULL wird die neue Singleton diskussion ;-)

wenn das so weitergeht eroeffne ich einen Singleton thread

Edit: ich versteh nicht was alle mit "eigenen NULL Objekte" meinen ? man muss kein neues Objekt erzeugen, wie eine neue art von Collection... es ist einfach eine leere.
 

Landei

Top Contributor
mit solch allgemeinen Aussagen kann ich leider nichts anfangen,
ich weiß nicht wie in Haskell ein JFrame oder 1000 andere Klasse mit 10.000 Klassenattributen definiert ist,
Haskell ist nicht objektorientiert, es hat Typen, aber keine Klassen im OO-Sinn.

ob für jede Klasse manuell ein eigenes Null-Objekt definiert ist usw.
Wie oft muss ich das Option-Pattern noch erklären?

ähm, ja, genau wie in Java: if (x == null) { throw Exception(); }

kürzere Syntax ist bisschen was anderes als 'null existiert nicht'?

falls der Compiler das automatisch beim Aufrufer prüft wäre man fast wieder bei
'Variable darf man nicht null zuweisen'

das ist natürlich interessantes Konzept, bisher konntest du dich zu diesem Punkt noch nicht durchdringen
Es besteht ein großer Unterschied, ob ich in einer Methode alle Argumente mit x == null überprüfe, oder ob man schon an der Argumentliste, also der öffentlichen API, sehen kann, das null nicht erlaubt ist.


ok, da stehts ja doch,
und da ist wie gesagt meine Frage: zwingt einen eine solche Sprache, zu allen Klassen ein Null-Objekt anzulegen?
oder anderenfalls immer eine Exception zu werfen falls etwas nicht initialisiert wurde?

über etwas zu meckern ist leicht, aber ohne eine Alternative aufzuzeigen?
ich sehe keine andere Möglichkeit bzw. ich verweise auf diverse andere Probleme, die versteckte Standardwerte zur Folge haben
Eine mögliche Antwort heißt Option, eine generische Wrapperklasse, einmal definiert. Aber das hatten wir schon x-mal.

Container haben eine einfache feste Semantik,
ist leer? ja/ nein
get/ set/ iterate

selbst das wäre übrigens automatisch erstellt für einen Computer wohl nicht sinnvoll zu lösen sein,
der würde bei Standard-Rückgabewerten bei isEmpty() false zurückgeben und bei isNotEmpty() genauso -> Chaos

man muss also manuell eigene NULL-Objekte definieren,
und das ist ja schon länger meine Frage: zwingt die Sprache den Programmierer wirklich, zu jeder Klasse ein NULL-Objekt zu definieren?
für sich schon ungeheuerlich,
aber wenn, dann habe ich glaube ich noch paar weitere Punkte auf Lager,

ohne NULL-Objekt sehe ich noch weniger durch, wie das alles funktionieren soll
Option, Option, Option

Lies doch bitte, bitte einfach mal Null ist keine Option… eSCALAtion Blog

Ich weiß nicht, wie du auf die Idee kommst, dass du für jede Klasse einen eigenes Null-Objekt brauchst, wofür haben wir Generics?
 
S

SlaterB

Gast
Edit: ich versteh nicht was alle mit "eigenen NULL Objekte" meinen ?

damit meine ich extra Code, ein spezielles selbst-programmiertes Sonder-Objekt, so wie

Java:
    /**
     * The empty list (immutable).  This list is serializable.
     *
     * @see #emptyList()
     */
    public static final List EMPTY_LIST = new EmptyList();

    /**
     * Returns the empty list (immutable).  This list is serializable.
     *
     * <p>This example illustrates the type-safe way to obtain an empty list:
     * <pre>
     *     List&lt;String&gt; s = Collections.emptyList();
     * </pre>
     * Implementation note:  Implementations of this method need not
     * create a separate <tt>List</tt> object for each call.   Using this
     * method is likely to have comparable cost to using the like-named
     * field.  (Unlike this method, the field does not provide type safety.)
     *
     * @see #EMPTY_LIST
     * @since 1.5
     */
    public static final <T> List<T> emptyList() {
	return (List<T>) EMPTY_LIST;
    }

    /**
     * @serial include
     */
    private static class EmptyList
	extends AbstractList<Object>
	implements RandomAccess, Serializable {
	// use serialVersionUID from JDK 1.2.2 for interoperability
	private static final long serialVersionUID = 8842843931221139166L;

        public int size() {return 0;}

        public boolean contains(Object obj) {return false;}

        public Object get(int index) {
            throw new IndexOutOfBoundsException("Index: "+index);
        }

        // Preserves singleton property
        private Object readResolve() {
            return EMPTY_LIST;
        }
    }
in java.util.Collections

für 10-100 einfache Klassen, die man überall braucht, ist das leicht, am besten sogar in der API vorgegeben,
aber bei jeder eigenen Person-Klasse, jedem ActionListener, jedem Hibernate-Proxy usw...
 
S

SlaterB

Gast
Option, Option, Option

Lies doch bitte, bitte einfach mal Null ist keine Option… eSCALAtion Blog

Ich weiß nicht, wie du auf die Idee kommst, dass du für jede Klasse einen eigenes Null-Objekt brauchst, wofür haben wir Generics?

das ist doch keine Alternative, man kann doch nicht jede einzelne Variable in einem Programm in Option umschreiben

Java:
class Person {
  String name;
  Adresse adresse;
  Person vater;
  Person mutter;
  ...
  evtl. getter/setter, vielleicht auch public-Zugriff
}
wie funktioniert das in echt, niemand will doch

Java:
class Person {
  Option<String> name = new Option();
  Option<Adresse> adresse = new Option();
  Option<Person> vater = new Option();
  Option<Person> mutter = new Option();
  ...
  evtl. getter/setter, vielleicht auch public-Zugriff
}
schreiben?

hast du vielleicht längere Code-Beispiele, wie programmierst du das in Scala?
 

Landei

Top Contributor
Ich schätze, dass in einem normalen Java-Programm höchstens 25% aller Variablen jemals mit null belegt werden. Wenn man etwas mehr darauf achtet, kann man diesen Wert wahrscheinlich auf 10% drücken.

Dass Option "unbequem" ist, liegt nicht am Konzept, sondern an der Umständlichkeit von Java (bessere Typinferenz in Java7 hilft schon etwas). Im Übrigen dient Option auch der Dokumentation: Es ist ein großes Warnschild, das diese Werte eben eventuell nicht initialisiert sind.

Ich denke, es ist auch nicht so wild, wenn lokale Variablen mit null hantieren und auf übliche Weise gegen null getestet werden, insbesondere wenn man es mit langatmigem Java zu tun hat. Das Problem wird ja es dadurch schlimm, dass Nullreferenzen zurückgegeben werden und als Argumente übergeben werden, also aus ihrem Kontext entkommen (ähnlich wie veränderliche Daten nicht unbedingt "böse" sind, aber eben auch so lokal wie möglich eingekastelt werden sollten).

[edit]
Vielleicht nicht das beste Beispiel (zu viele Dinge, die es in Java nicht gibt), aber z.B. hier
lazyEvaluation.scala | The Scala Programming Language

Es ist schon bezeichnend, dass ich Mühe hatte, auf der Scala-Seite überhaupt ein Beispiel zu finden, was meine These untermauert, dass null oft nur ein Designfehler ist.
Eine typische Anwendung in Scala ist Map, wo die get-Methode eine Option zurückliefert. Es gibt aber z.B. auch eine alternative Methode getOrElse, bei der man (wie in Java bei Properties) einen Default-Wert angeben kann (oder eine Exception werfen).
In Scala arbeitet Option gut mit den restlichen Konstrukten zusammen und stört kaum. Eine Liste aus Options kann z.B. man mit "flatten" einfach zu einer Liste mit Werten machen (Nones werden weggeworfen)
 
Zuletzt bearbeitet:

Landei

Top Contributor
wie kann das möglich sein, wenn null in einer Sprache verboten ist?!
wir drehen uns im Kreis

Ich sprach über Java. Und wegen der Java-Kompatibilität ist auch in Scala null "erlaubt", wird aber in reinem Scala-Code normalerweise nicht verwendet (da Option gut "integriert" ist und einfach besser passt). Kein null haben z.B. Haskell und Self.
 
S

SlaterB

Gast
also mit EMPTY_LIST usw. ist das dann nicht mehr vergleichbar, das wurde nämlich schon oft genug bei 'null böse' genannt,

ich erinnere nur an die Diskussion um mein unsägliches Beispiel
Java:
Person x = db.ladePerson("tommy");
String y = x.getEhePartner().getVater().getGrabstein().getInschrift();
da ging es lange darum, dass doch am Ende ein String rauskommen soll, egal welches Objekt zwischendurch null ist,

Option hilft hier nicht weiter, korrekt?



--------

natürlich kann man
Java:
Option<Person> x = db.ladePerson("tommy");
if (x.isEmpty()) {
return "";
} else {
..
}
verwenden,
aber das ist ja nicht viel anders als

Java:
Person x = db.ladePerson("tommy");
if (x == null) {
return "";
} else {
..
}
es ist sicherer, es ist programmatisch sauberer vorgegeben,
aber bitte, wer einen solchen Rückgabewert nicht selber vorher prüft..

das ist ja erschreckend unwichtig

getOrElse() kann man hier nicht nutzen, denn dann müsste man ein NULL-Objekt übergeben, wogegen wir uns ja zum Glück doch einig sind
Java:
Option<Person> x = db.ladePerson("tommy");
return x.getOrElse(Person.EMPTY_PERSON).get...;
über 4-5 Stufen mit Ehepartner, Grabstein usw. wäre das noch schlimmer,


also Option als Markierung, dass etwas null sein kann und der Test erforderlich ist,
das kann ich als ein seriöses Konzept akzeptieren, besonders sinnvoll ist das aber nicht,


hier und jetzt habe ich die Wahl das in mein zukünftigen Java-Programme einzubauen und mache es nicht,
genau wie prakisch keine Java-API, kein Java-Lehrbuch auf dieser Welt..,

in einzelnen Fällen ist es nützlich, manche Maps oder einzelnen Methode habe ich bereits in meinen Programm

T getValue(String key, T defaulValue) // defaultValue wenn sonst null

um ein if abzukürzen, aber null ganz verbieten, nein



edit:
würde man null verbieten ginge gar nicht mehr das Feature

Java:
Person x = db.ladePerson("tommy");
String y = x?.getEhePartner()?.getVater()?.getGrabstein()?.getInschrift();
und nur mit Option kriegt man das ja nicht ähnlich hübsch hin, oder?
so gesehen wäre Option + kein null gar ein Rückschritt, würde diese tolle Syntax verhindern (sofern es sie in Java je geben wird ;) ) ?
 
Zuletzt bearbeitet von einem Moderator:

Landei

Top Contributor
Man kann Options ähnlich wie "Elvis" verwenden:

Scala:
Code:
val map = Map(1 -> Map(2 -> (Map(3 -> "X")))
val x = map.get(1).flatMap(_.get(2).flatMap(_.get(3)))
//--> x: Option[java.lang.String] = Some(X)
val y = map.get(4).flatMap(_.get(2).flatMap(_.get(3)))
//--> y: Option[java.lang.String] = None
 
S

SlaterB

Gast
stimmt, da kann man schon was drehen wenn Option ein SprachElement ist, dann kann man Abkürzungen einbauen,
dein Beispiel klingt etwas gefährlich, gilt das nur für Maps oder für beliebige Objekte?

geht
Option<Person> x = ..;
Option<String> y = x?.getVaterOption()?.getName()
?

naja, selbst wenn bisher nicht, könnte man es immer noch einbauen, denkbar wäre es
 

Landei

Top Contributor
Für beliebige Objekte (flatMap ist eine Methode von Option). Ist natürlich in Java wegen der fehlenden Closures nicht wirklich attraktiv, aber ob man Elvis für null oder für Options (analog zu flatMap) definiert, bleibt sich eigentlich gleich.

Übrigens wird oft übersehen, dass die üblichen Nulltests ein kleines Problem haben:
Java:
public class NullTest {
  static String s = null;
  
  public static void main(String... args) throws InterruptedException {
     new Thread(){
       public void run() {
         while(true) {
           s = System.currentTimeMillis() % 2 == 0 ? null : "Hallo!";
         }
       }
     }.start();  
     
     while(true) {
       if(s != null) {
         Thread.sleep(1); //oder irgendwas anderes, was etwas Zeit braucht
         System.out.println(s.length());
       }
     }
  }
}
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
F String equals NULL Problem Java Basics - Anfänger-Themen 4
X Datentypen String.equals funktioniert nicht Java Basics - Anfänger-Themen 5
L String überprüfen mit .equals .contains oder .matches? Java Basics - Anfänger-Themen 1
F Erste Schritte Hilfe bei Übung zu String equals() und Schleifen Java Basics - Anfänger-Themen 8
S equals Methode bei String Java Basics - Anfänger-Themen 5
K String - Equals Java Basics - Anfänger-Themen 2
D Problem mit string.equals bzw string.contains Java Basics - Anfänger-Themen 4
T Problem mit der while(!string.equals("x")) Java Basics - Anfänger-Themen 2
L String mit equals vergleichen Java Basics - Anfänger-Themen 6
D String#equals + String#charAt Java Basics - Anfänger-Themen 5
T [SOLVED] Java String equals funktioniert nicht Java Basics - Anfänger-Themen 5
B String.equals(Object) anstatt "=" Java Basics - Anfänger-Themen 3
G String-Vergleich: Was ist besser "equals()" oder & Java Basics - Anfänger-Themen 4
krgewb String mit Datumsangabe in Long umwandeln Java Basics - Anfänger-Themen 2
D String Groß/Kleinschreibung Ignorieren Java Basics - Anfänger-Themen 4
D Map<String, Integer> sortieren und der reinfolge nach die Glieder abfragen Java Basics - Anfänger-Themen 3
J Ähnlichen String in Liste finden Java Basics - Anfänger-Themen 6
Kartoffel_1 String transformation Java Basics - Anfänger-Themen 7
H String-Operation replace() - Zeichenkette verdoppeln Java Basics - Anfänger-Themen 2
K String analysieren Java Basics - Anfänger-Themen 27
Beowend String zu Date parsen Java Basics - Anfänger-Themen 1
Beowend String auf Satzzeichen überprüfen? Java Basics - Anfänger-Themen 6
H Liste nach String-Länge sortieren Java Basics - Anfänger-Themen 1
String in ArrayList umwandeln Java Basics - Anfänger-Themen 1
I Sass Compiler und String erhalten? Java Basics - Anfänger-Themen 7
Avalon String in Double bzw. Währung konvertieren Java Basics - Anfänger-Themen 6
T Methode akzeptiert String nicht Java Basics - Anfänger-Themen 18
F Arraylist<String>Ein Wort pro Zeile Java Basics - Anfänger-Themen 6
J Schlüsselworte Prüfen, ob ein bestimmtes, ganzes Wort in einem String enthalten ist. Java Basics - Anfänger-Themen 6
N String überprüfen Java Basics - Anfänger-Themen 3
E String zerlegen aus args Java Basics - Anfänger-Themen 1
M Long-Typ in String-Änderung führt zu keinem Ergebnis bei großer Zahl Java Basics - Anfänger-Themen 11
Ostkreuz String Exception Java Basics - Anfänger-Themen 8
W Items löschen aus String Array vom Custom Base Adapter Java Basics - Anfänger-Themen 2
MoxMorris Wie macht man String[] = String[] aus einer anderer Methode? Java Basics - Anfänger-Themen 18
J String Filter Java Basics - Anfänger-Themen 5
S String Array Buchstaben um einen gewissen Wert verschieben Java Basics - Anfänger-Themen 4
R Größter zusammenhängender Block gleicher Zeichen im String Java Basics - Anfänger-Themen 1
XWing Randomizer mit einem String Java Basics - Anfänger-Themen 2
D 2D Char Array into String Java Basics - Anfänger-Themen 2
H Cast von Float nach String klappt nicht Java Basics - Anfänger-Themen 12
I Zerlegen von String Java Basics - Anfänger-Themen 3
B Beliebiger String gegeben Suche Datum in String Java Basics - Anfänger-Themen 6
I String Java Basics - Anfänger-Themen 4
I API - zurückgegebener JSON String lesen und in Entity konvertieren Java Basics - Anfänger-Themen 2
H Zu langen String aufteilen - bequeme Methode? Java Basics - Anfänger-Themen 14
W String einer Textdatei in einzelne Stringobjekte pro Zeile aufteilen Java Basics - Anfänger-Themen 14
belana wie am besten 2D Array von String to Integer Java Basics - Anfänger-Themen 18
J Java To String Methode, Array mit For-Schleife Java Basics - Anfänger-Themen 2
M Kommandozeilenparamter als EINEN String werten Java Basics - Anfänger-Themen 5
M RandomAccessFile int und String gleichzeitig in einer Datei Java Basics - Anfänger-Themen 49
M Prüfen on eine Zahl im String enthalten ist Java Basics - Anfänger-Themen 3
Distanz zwischen zwei Zeichenfolgen in einem String bestimmen Java Basics - Anfänger-Themen 5
Substring in einem String finden Java Basics - Anfänger-Themen 13
BeginnerJava String mit vorgegebener Länge und Buchstaben erzeugen/ mit Leerstellen Java Basics - Anfänger-Themen 8
I Eindeutiger String mit maximaler Anzahl an Zeichen Java Basics - Anfänger-Themen 11
H Interface Wieso "List<String> list = new ArrayList<>[…]" Java Basics - Anfänger-Themen 4
JavaBeginner22 Integer in String umwandeln Java Basics - Anfänger-Themen 7
HolyFUT JSON String in Java Object schreiben - Anführungszeichen rauskriegen? Java Basics - Anfänger-Themen 17
Fodoboo131 RegEx- Umwandlung von String in ausführbares Objekt/ Befehl Java Basics - Anfänger-Themen 9
HolyFUT Input/Output Leerzeichen aus String entfernen - klappt nicht! Java Basics - Anfänger-Themen 13
viktor1 Methoden Methode schreiben static void readText (String filename) {...} zu WordHistogramSample.java Java Basics - Anfänger-Themen 13
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
G Position einer unbekannten 3-stelligen-Zahl in einem String finden Java Basics - Anfänger-Themen 15
T String Array Fehler beim Index Java Basics - Anfänger-Themen 3
H Erste Schritte Nach einer Zahl n soll n Mal der String untereinander ausgegeben werden Java Basics - Anfänger-Themen 3
Alen123 String wiederholen mit Schleifen Java Basics - Anfänger-Themen 1
A String split funktioniert nicht, wenn mehr als 1 Ziffer vor dem Zeichen steht nach dem er trennen soll? Java Basics - Anfänger-Themen 4
T String splitten Java Basics - Anfänger-Themen 3
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
J Datentypen String in File konvertieren funktioniert nicht Java Basics - Anfänger-Themen 4
T Platzhalter in String? Java Basics - Anfänger-Themen 14
M String mit Variable vergleichen Java Basics - Anfänger-Themen 9
I String Kombination erstellen anhand fortlaufender Zahl (Vertragsnummer) Java Basics - Anfänger-Themen 13
Fats Waller Compiler-Fehler Kann ich einen String und die Summe zweier Char Werte mittels der println Anweisung ausgeben Java Basics - Anfänger-Themen 4
M Wie kann eine Methode (string) eine andere Methode (void) mit zufälligen int-Werten aufrufen? Java Basics - Anfänger-Themen 4
P9cman Vokale in einem String überprüfen mittels Rekursion Java Basics - Anfänger-Themen 8
schredder Strings und reguläre Ausdrücke - Methode mit return string.matches Java Basics - Anfänger-Themen 5
R Ein Multidimensionales String Array initialisieren und Deklarieren Java Basics - Anfänger-Themen 2
H String Repräsentation eines Rechtecks mit Instanz-Methode Java Basics - Anfänger-Themen 8
Dorfschmied Kartesisches Produkt von zwei Liste mit Hashmaps<String,String> erstellen Java Basics - Anfänger-Themen 4
S String mit Int input vergleichen Java Basics - Anfänger-Themen 5
C String/Char-API Java Basics - Anfänger-Themen 13
U Char zu einem String machen Java Basics - Anfänger-Themen 1
B Anzahl Nullen uns Einsen in String ermitteln Java Basics - Anfänger-Themen 3
T Leerzeichen im String entfernen Java Basics - Anfänger-Themen 6
Jose05 Nullpointerexception bei Umwandlung von String zu int Java Basics - Anfänger-Themen 2
O Ich habe einen String und soll mit matches schauen, ob ein Buchstabe zu einer geraden ANzahl im String vorkommt, wie soll das gehen? Java Basics - Anfänger-Themen 7
M String beim einlesen formatieren Java Basics - Anfänger-Themen 12
N null in String replacen Java Basics - Anfänger-Themen 16
R Compiler-Fehler JTable mit XML befüllen | The constructor JTable(Object[], String[]) is undefined Java Basics - Anfänger-Themen 10
M Eclipse kennt keine String Klasse mehr Java Basics - Anfänger-Themen 1
M Frage zur Methode split der Klasse String Java Basics - Anfänger-Themen 32
D String mit int multiplizieren? Java Basics - Anfänger-Themen 16
H Überprüfen ob String Array leer ist Java Basics - Anfänger-Themen 4
A Korrigierte <String> Liste zurückgeben Java Basics - Anfänger-Themen 22
C In String, Buchstaben ersetzen durch andere Buchstaben Java Basics - Anfänger-Themen 26
Poppigescorn String mit mehreren Wörtern füllen? Java Basics - Anfänger-Themen 4
I String Expression mit Java validieren (true / false) Java Basics - Anfänger-Themen 34
B String - Wörter finden, welches Punkt und entsprechender Pre / Suffix hat? Java Basics - Anfänger-Themen 30

Ähnliche Java Themen

Neue Themen


Oben