Markus Pitha: Wie prüfen ob Variable existiert + package Frage.

Hallo,
Ich habe in einer Klasse folgende Methode:

void person_hinein(int x)    {
anzahl_personen += x;
}
Zuerst wollte ich danach prüfen, dass mir bei nicht übergebenem Wert die Variable anzahl_personen einfach um eins inkrementiert wird, und zwar ungefähr so:

void person_hinein(int x)    {
      if (x == true)
      anzahl_personen += x;
      else
      anzahl_personen ++;
}

if (x) darf ich in Java sowieso nicht schreiben, aber wenn ich etwas wie if ((boolean)x == true) schreibe, meckert der Compiler auch. Ich kann natürlich eine zweite Methode..

void person_hinein()    {
anzahl_personen++;
}

..schreiben, was dann auch funktioniert, aber es erscheint mir ziemlich umständlich. Wie kann man das eleganter lösen?

Mein 2. Problem liegt an den ersten beiden Beispielen (jene, wo "package v1" ganz oben steht) hier: http://www.galileocomputing.de/openbook/javainsel4/javainsel_06_000.htm#Rxx365java06000040001AC1F03F102
Ich habe ein Verzeichnis angelegt, das genauso v1 heißt, und die Klassen darin platziert, aber ich konnte die 2. Klasse nicht kompilieren (weder meine eigens veränderte noch die Orginale aus der Doku). Ich bekomme Fehler wie:

discobetrieb.java:5: cannot resolve symbol
symbol  : class disco
location: class disc.discobetrieb
   disco abzappler = new disco();
          ^
discobetrieb.java:5: cannot resolve symbol
symbol  : class disco
location: class disc.discobetrieb
   disco abzappler = new disco();

2 errors.

(discobetrieb heißt meine 2. Klasse und nicht DiskoFieber wie in der Doku).

Das Seltsame ist, wenn ich die "package" Angabe aus beiden Klassen entferne, kann ich beide kompilieren und ausführen. Was bringt dieses package nun, und warum funktionieren nicht mal das Orginalbeispiel, wenn "package" angeführt ist? Was muss man bedenken, oder liegt ein Fehler in der Doku vor?

Markus.

--
sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
  1. Hi,

    Zuerst wollte ich danach prüfen, dass mir bei nicht übergebenem Wert die Variable anzahl_personen einfach um eins inkrementiert wird, und zwar ungefähr so:

    "bei nicht übergebenem Wert" bedeutet, dass Du eine neue Methode mit entsprechender Signatur schreibst. Andernfalls ließe sich die Methode nicht aufrufen.

    void person_hinein()    {
    anzahl_personen++;
    }
    ..schreiben, was dann auch funktioniert, aber es erscheint mir ziemlich umständlich. Wie kann man das eleganter lösen?

    Indem Du von dieser Methode aus die andere aufrufst.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hi,

      Indem Du von dieser Methode aus die andere aufrufst.

      dann habe ich aber trotzdem wieder 2 Methoden, was ich aber vermeiden will. Ich suche quasi das Java Äquivalent zu if (x).

      Markus.

      --
      sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
      1. Hallo Markus,

        In Java wird (wie in vielen nicht-Scriptsprachen) eine Methode nicht nur über ihren Namen, sondern auch über ihre Parameter identifiziert.
        Die Methode tuWas(int i) kannst Du nicht ohne einen Parameter vom Typ int aufrufen. Wenn Du tuWas() schreibst, rufst Du eine andere Methode auf, die es natürlich geben muss.
        Das ist eigentlich ziemlich praktisch. Die von Chetah vorgeschlagene Lösung:

        tuWas() {
          tuWas(1);
        }

        tuWas(int i) {
          //blablub
        }

        ist auch keineswegs ungeschickt und viel sauber und fehlerunanfälliger als das Vorhandensein von Parametern zu überprüfen und ähnliche in Scriptsprachen übliche Hacks.

        Grüße

        Daniel

        1. Hallo,

          In Java wird (wie in vielen nicht-Scriptsprachen) eine Methode nicht nur über ihren Namen, sondern auch über ihre Parameter identifiziert.
          Die Methode tuWas(int i) kannst Du nicht ohne einen Parameter vom Typ int aufrufen. Wenn Du tuWas() schreibst, rufst Du eine andere Methode auf, die es natürlich geben muss.

          Alles klar, danke.

          ist auch keineswegs ungeschickt und viel sauber und fehlerunanfälliger als das Vorhandensein von Parametern zu überprüfen und ähnliche in Scriptsprachen übliche Hacks.

          So kann man es natürlich auch wieder betrachten. Andererseits ist Java ziemlich wuchtig und wollte schlanken Code schreiben, da Java ohnehin schon ziemlich langsam ist.

          Weißt du zufällig noch, warum das mit dem "package" nicht klappt?

          Markus.

          --
          sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
          1. Hallo Markus,

            Hallo,

            So kann man es natürlich auch wieder betrachten. Andererseits ist Java ziemlich wuchtig und wollte schlanken Code schreiben, da Java ohnehin schon ziemlich langsam ist.

            So langsam ist Java erstens auch wieder nicht (schon gar nicht im vergleich zu Scriptsprachen) und zweitens ist es bestimmt nicht deswegen schneller oder langsamer, weil Du eine Methode mehr oder weniger hast.
            Wenn Dein Javaprogramm wirklich langsam ist, dann vermutlich, weil Du ungeeignete Algorithmen benutzt oder Objekte erzeugst und dem GC nicht ermöglichst, sie wieder zu löschen o.ä.

            Weißt du zufällig noch, warum das mit dem "package" nicht klappt?

            Mehr als Axel schon gesagt hat, kann ich dazu auch nicht sagen.

            Grüße

            Daniel

            1. Hallo,

              Wenn Dein Javaprogramm wirklich langsam ist, dann vermutlich, weil Du ungeeignete Algorithmen benutzt oder Objekte erzeugst und dem GC nicht ermöglichst, sie wieder zu löschen o.ä.

              Nun, ich habe bisher nichts Großes geschrieben. zB das hier:

              import javax.swing.*;

              class stringvergleich    {
                       public static void main (String args[])    {
                String eingabe1 = JOptionPane.showInputDialog("Gib einen ersten String ein, der dann mit dem 2. verglichen wird: ");
                String eingabe2 = JOptionPane.showInputDialog("Gib einen zweiten String ein: ");
                            if (eingabe1.equals(eingabe2) == true)
                     System.out.println("Die Strings sind gleich :)");
                     else
                     System.out.println("Die Strings sind nicht gleich :(");
                System.exit(0);
                }
              }

              Selbst so ein Programm braucht eine Sekunde zum Kompilieren. (Ein C Programm ist bei Enter Druck kompiliert). Desweiteren warte ich mal ca 2 Sekunden, bis das Popup aufgeht. Nach der Ausgabe "Die Strings sind gleich /nicht gleich" warte ich nochmal eine Sekunde, bis wieder die bash erscheint.
              Ich findedas schonrecht langsam.

              Markus.

              --
              sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
              1. Hallo Markus,

                Nun, die VM braucht natürlich immer etwas, bis sie gestartet ist und auch der Javacompiler benötigt die meines Wissens.
                Nachdem Dein Programm gestartet ist, läuft es allerdings nicht langsam. Der zweite Dialog erscheint sofort nachdem der erste geschlossen wurde. Selbiges gilt für die Ausgabe.
                Swing ist sicher langsam im vergleich zu Toolkits, die in C geschrieben sind. Aber bei so einem mikrigen Dialog merkt man das wirklich nicht.
                Was die Ausgabe von Text auf der Konsole angeht: Das dürfte kaum schneller gehen, schließlich findet da nur ein einziger Methodenaufruf statt. Die Methode selbst ist nativ implementiert.
                Sicher ist Java in vielen Bereichen langsamer als C. Vor allem durch den ganzen Overhead, den Objekte, der GC usw mit sich bringen.
                Für sehr viele Aufgaben ist das aber bei Weitem schnell genug.

                Grüße

                Daniel

              2. Hallo,

                Selbst so ein Programm braucht eine Sekunde zum Kompilieren. (Ein C Programm ist bei Enter Druck kompiliert).

                Ein C-Programm _mit GUI_ ist bei Enter-Druck compiliert? Was zu beweisen wäre ;-)).

                Desweiteren warte ich mal ca 2 Sekunden, bis das Popup aufgeht. Nach der Ausgabe "Die Strings sind gleich /nicht gleich" warte ich nochmal eine Sekunde, bis wieder die bash erscheint.

                Äpfel und Birnen ;-))

                1. Dein C-Tool mit GUI würde nur auf der Plattform laufen, auf der es compiliert wurde. Java-Bytecode läuft aber in _jeder_ kompatiblen Java Virtual Machine. Schreibe ein plattformübergreifend laufendes C-Tool und vergleiche dann ;-)).

                2. Du nutzt mit JOptionPane nur eine Swing-Klasse, die sich direkt, ohne Framework drumrum, von der JVM aufrufen lässt. So etwas ist kein Vergleichskriterium. Schreibe ein echtes GUI mit Framework und vergleiche dann ;-)).

                3. Mit System.exit(0); beendest Du nicht nur das Programm, sondern hier auch die JVM. Es laufen garbage collectors, die den Arbeitsspeicher von Müll befreien.

                viele Grüße

                Axel

                1. Hi,

                  1. Dein C-Tool mit GUI würde nur auf der Plattform laufen, auf der es compiliert wurde.

                  Nö. Das C-Tool läuft nur auf der Plattform, _FÜR DIE_ es compiliert wurde. Auf welcher Plattform die Compilation stattfindet, ist irrelevant.

                  cu,
                  Andreas

                  --
                  Warum nennt sich Andreas hier MudGuard?
                  Schreinerei Waechter
                  Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
  2. Hallo,

    Mein 2. Problem liegt an den ersten beiden Beispielen (jene, wo "package v1" ganz oben steht) hier: http://www.galileocomputing.de/openbook/javainsel4/javainsel_06_000.htm#Rxx365java06000040001AC1F03F102
    Ich habe ein Verzeichnis angelegt, das genauso v1 heißt, und die Klassen darin platziert, aber ich konnte die 2. Klasse nicht kompilieren (weder meine eigens veränderte noch die Orginale aus der Doku). Ich bekomme Fehler wie:

    discobetrieb.java:5: cannot resolve symbol
    symbol  : class disco
    location: class disc.discobetrieb
       disco abzappler = new disco();

    Nach den Fehlermeldungen sieht es aber so aus, als würde das package disc heißen. Was denn nun?

    Beispiel Windows:

    Im Ordner C:\JavaBsp\v1\ liegen:

    eins.java
    -----------------------------------------------
    package v1;
    public class eins {
      public String name = "Klasse eins";
    }
    -----------------------------------------------
    zwei.java
    -----------------------------------------------
    package v1;
    public class zwei {
      public static void main( String args[] ) {
         eins e = new eins();
         System.out.println(e.name);
      }
    }
    -----------------------------------------------
    Compilieren:
    C:\JavaBsp>javac .\v1\zwei.java
    compiliert beide Klassen.

    Starten:
    C:\JavaBsp>java v1.zwei

    http://java.sun.com/docs/books/tutorial/java/interpack/managingfiles.html

    viele Grüße

    Axel

    1. Hallo,
      ja es heißt disc eigentlich. Wollte mich nur auf das Bsp. beziehen. Wenn ich es aber so mache, dass ich von "außerhalb" kompiliere, funktioniert das zwar, aber wenn ich dann discobetrieb starte, bekomme ich folgendes:

      markus@gentoo disc $javac discobetrieb
      Exception in thread "main" java.lang.NoClassDefFoundError: discobetrieb (wrong name: disc/discobetrieb)
       at java.lang.ClassLoader.defineClass0(Native Method)
       at java.lang.ClassLoader.defineClass(ClassLoader.java:502)
       at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
       at java.net.URLClassLoader.defineClass(URLClassLoader.java:250)
       at java.net.URLClassLoader.access$100(URLClassLoader.java:54)
       at java.net.URLClassLoader$1.run(URLClassLoader.java:193)
       at java.security.AccessController.doPrivileged(Native Method)
       at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
       at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
       at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)

      markus@gentoo disc $
      ?

      Markus.

      --
      sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
      1. Hallo,

        ja es heißt disc eigentlich. Wollte mich nur auf das Bsp. beziehen. Wenn ich es aber so mache, dass ich von "außerhalb" kompiliere, funktioniert das zwar, aber wenn ich dann discobetrieb starte, bekomme ich folgendes:

        Ein Package liegt später üblicherweise _in_ einem Archiv (JAR) gepackt. Das ist der Hauptgrund für die Verwendung von Packages. Es ist also sehr unwahrscheinlich, dass jemand _in_ diesem JAR steckt und von dort den Java-Interpreter startet ;-))

        Du musst es also auch von "außerhalb" starten. Du bist also, wie beim Compilieren, ein Verzeichnis über disc und rufst auf:

        java disc.discobetrieb

        viele Grüße

        Axel