[OOP] Auf eine Variable aus meherer Klassen zugreifen

florianA06

Mitglied
Guten Abend liebe Foren Gemeinde,

zu Anfang möchte ich mich entschuldigen, falls ich in den falschen Thread schreibe. Dennnoch habe ich mich vorher nach der Lösung erkundet (sowohl in diesem Forum, als auch via. Google), habe aber keine für mich passende Lösung gefunden.

Nun zu meinem Problem:
Ich habe insgesamt 3 Klassen in einem Paket. Nur eine Klasse (Hauptklasse) kann von Außerhalb genutzt werden alle anderen nicht.

FiLo-Klasse:
Java:
public class FiLo {
    private char mode;
    private boolean noUI;

    private static List<String> paths;
    private static List<String> fileExtensions;

    public FiLo(String configFile) {
        new ConfigurationFile(configFile);
    }

    public FiLo(char mode, boolean noUI, List<String> paths, List<String> fileExtensions) {
        paths = new ArrayList<>();
        fileExtensions = new ArrayList<>();

        this.mode = mode;
        this.noUI = noUI;
        this.paths = paths;
        this.fileExtensions = fileExtensions;
    }

    char getMode() {
        return mode;
    }

    void setMode(char mode) {
        this.mode = mode;
    }

    static List<String> getPaths() {
        return paths;
    }

    static void setPaths(List<String> paths) {
        FiLo.paths = paths;
    }

    static List<String> getFileExtensions() {
        return fileExtensions;
    }

    static void setFileExtensions(List<String> fileExtensions) {
        FiLo.fileExtensions = fileExtensions;
    }

    public void start() {
        new FilesAndDirectories();
    }

ConfigurationFile-Klasse:
Java:
class ConfigurationFile{
    ConfigurationFile(String configFilePath) {

        Path configFile = Paths.get(configFilePath);

        try(BufferedReader reader = Files.newBufferedReader(configFile)) {
            String line;
            int i = 0;

            while((line = reader.readLine()) != null) {
                if(!(line.startsWith("#"))) {
                    if(line.startsWith("*")) {
                        if(i == FiLo.getPaths().size()) { i = 0; }
                        line = line.replace("*", "");

                        FiLo.getFileExtensions().add(i, line);
                    } else {
                        FiLo.getPaths().add(i, line);
                    }
                    i++;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Die Listen (List<String> path & fileExtensions (in der Klasse FiLo)) sollen auch von der anderen Klasse verfügbar sein. So wie der Code jetzt aussieht, wirft der Compiler eine NullPointerException.

Ich hatte das vorher schon mit "getter'n" und "setter'n" probiert, da hat man allerdings das Problem, dass ich mehrer Objekte habe (da noch eine weiter Klasse vorhanden ist), und diese dann unterschiedliche Werte haben.

Wie löst man das Problem am besten? (Mit Vererbung?)

Freundliche Grüße
Florian

P.S. sorry, für den langen Post
 
Ja eigentlich schon. -> Es muss keine Instanz erstellt werden bzw. ein Objekt, sodass ich einfach mit dem Klassennamen (in diesem Falle FiLo) auf die Variable zugreifen kann.
 
Das ist schon mal ein Anfang.
Wenn du jetzt in den Konstruktor schaust siehst du, dass deine Variablen erst initialisiert werden, wenn du ein Objekt deiner FiLo Klasse erstellst.
Jetzt bring die 2 Sachen mal in Verbindung und überleg warum da eine NPE geworfen wird und überleg wie du es schaffst diese weg zu bekommen.

Kleiner Hinweis für die Lösung: static ist gerade für den Anfang schlecht und sehr fehleranfällig 😉
 
Getter & Setter sind schon der richtige Weg - static ist genau der falsche.

Mehrere Objekte und Get-/Setter stehen sich nicht im Weg, sondern passen ziemlich gut zusammen, ohne dein konkretes Problem zu kennen kann man aber nur wenig sagen 😉
 
Ich danke erstmal für die Antworten.
Werde mich morgen/heute nochmal um das Problem kümmer.

P.S. ich möchte auch lieber Getter bzw. Setter verwenden, anstatt static
 
...so ich habe jetzt static komplett entfernt:
Java:
package de.florian.filo;

import java.util.ArrayList;
import java.util.List;

/**
* FiLo - A tool for searching different Files and Folders
*
* Created by Florian Abeln on 10.06.2017.
*/
public class FiLo {
    private char mode;
    private boolean noUI;
    private String configFile;

    private List<String> paths;
    private List<String> fileExtensions;

    FiLo() {}

    public FiLo(String configFile) {
        this.configFile = configFile;
    }

    public FiLo(char mode, boolean noUI, List<String> paths, List<String> fileExtensions) {
        paths = new ArrayList<>();
        fileExtensions = new ArrayList<>();

        this.mode = mode;
        this.noUI = noUI;
        this.paths = paths;
        this.fileExtensions = fileExtensions;
    }

    char getMode() {
        return mode;
    }

    void setMode(char mode) {
        this.mode = mode;
    }

    List<String> getPaths() {
        return paths;
    }

    void setPaths(List<String> paths) {
        this.paths = paths;
    }

    List<String> getFileExtensions() {
        return fileExtensions;
    }

    void setFileExtensions(List<String> fileExtensions) {
        this.fileExtensions = fileExtensions;
    }

    public void start() {
        new ConfigurationFile(configFile);
        new FilesAndDirectories();
    }


    public void debugOutput() {
        for(String element : paths) {
            System.out.println(element);
        }

        for(String element : fileExtensions) {
            System.out.println(element);
        }
    }
}

Allerdings gibt es immer noch eine NullPointerException. Liegt vielleicht der Faehler daran, dass die 2 Listen (List<String>) leer sind (bzw. keinen Inhalt haben) oder woran liegt es?
Der Code der anderen Klasse hat sich nicht verändert.

Freundliche Grüße
Florian

Edit

IntelliJ gibt folgende Meldung aus:
Code:
Exception in thread "main" java.lang.NullPointerException
    at de.florian.filo.ConfigurationFile.<init>(ConfigurationFile.java:34)
    at de.florian.filo.FiLo.start(FiLo.java:60)
    at de.florian.filo.Main.main(Main.java:12)
 
Hier der Code der Klasse:
Java:
package de.florian.filo;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

/**
* FiLo - A tool for searching different Files and Folders
*
* Created by Florian Abeln on 10.06.2017.
*/
class ConfigurationFile{
    ConfigurationFile(String configFilePath) {

        Path configFile = Paths.get(configFilePath);

        FiLo filo = new FiLo();

        try(BufferedReader reader = Files.newBufferedReader(configFile)) {
            String line;
            int i = 0;

            while((line = reader.readLine()) != null) {
                if(!(line.startsWith("#"))) {
                    if(line.startsWith("*")) {
                        if(i == filo.getPaths().size()) { i = 0; }
                        line = line.replace("*", "");

                        filo.getFileExtensions().add(i, line);
                    } else {
                        filo.getPaths().add(i, line);
                    }
                    i++;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
Einen (logischen) Fehler, der aber nicht zur Lösung beiträgt, ist gefunden (die Werte müssen in Z. 32 & 34 gesetzt werden (d.h. set und nicht get)).

So also die Komplette Exception:
Code:
Exception in thread "main" java.lang.NullPointerException
    at de.florian.filo.FiLo.setPathsElement(FiLo.java:48)
    at de.florian.filo.ConfigurationFile.<init>(ConfigurationFile.java:34)
    at de.florian.filo.FiLo.start(FiLo.java:60)
    at de.florian.filo.Main.main(Main.java:12)


Die Klasse FiLo.java:
Java:
package de.florian.filo;

import java.util.ArrayList;
import java.util.List;

/**
* FiLo - A tool for searching different Files and Folders
*
* Created by Florian Abeln on 10.06.2017.
*/
public class FiLo {
    private char mode;
    private boolean noUI;
    private String configFile;

    private List<String> paths;
    private List<String> fileExtensions;

    FiLo() {}

    public FiLo(String configFile) {
        this.configFile = configFile;
    }

    public FiLo(char mode, boolean noUI, List<String> paths, List<String> fileExtensions) {
        paths = new ArrayList<>();
        fileExtensions = new ArrayList<>();

        this.mode = mode;
        this.noUI = noUI;
        this.paths = paths;
        this.fileExtensions = fileExtensions;
    }

    char getMode() {
        return mode;
    }

    void setMode(char mode) {
        this.mode = mode;
    }

    List<String> getPaths() {
        return paths;
    }

    void setPathsElement(int index, String string) {
        paths.add(index, string);
    }

    List<String> getFileExtensions() {
        return fileExtensions;
    }

    void setFileExtensionsElement(int index, String string) {
        fileExtensions.add(index, string);
    }

    public void start() {
        new ConfigurationFile(configFile);
        new FilesAndDirectories();
    }


    public void debugOutput() {
        for(String element : paths) {
            System.out.println(element);
        }

        for(String element : fileExtensions) {
            System.out.println(element);
        }
    }
}

Die Klasse ConfigurationFile.java:
Java:
package de.florian.filo;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

/**
* FiLo - A tool for searching different Files and Folders
*
* Created by Florian Abeln on 10.06.2017.
*/
class ConfigurationFile{
    ConfigurationFile(String configFilePath) {

        Path configFile = Paths.get(configFilePath);

        FiLo filo = new FiLo();

        try(BufferedReader reader = Files.newBufferedReader(configFile)) {
            String line;
            int i = 0;

            while((line = reader.readLine()) != null) {
                if(!(line.startsWith("#"))) {
                    if(line.startsWith("*")) {
                        if(i == filo.getPaths().size()) { i = 0; }
                        line = line.replace("*", "");

                        filo.setFileExtensionsElement(i, line);
                    } else {
                        filo.setPathsElement(i, line);
                    }
                    i++;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Und Main.java:
Java:
package de.florian.filo;

/**
* Created by Florian on 10.06.2017.
*/
public class Main {

    public static void main(String[] args) {

        FiLo filo = new FiLo("config.txt");

        filo.start();
        filo.debugOutput();

    }

}

...ich hoffe habe nichts vergessen.

Freundliche Grüße
Florian

P.S: Was haltet ihr davon, in jeder Klasse eine Liste zustellen, die mit der Hauptklasse (FiLo.java) syncronisiert wird? Muss doch eine bessere Lösung geben.
 
Kleine Stolperfalle bei deinen Konstruktoren.
Wenn du den leeren Konstruktor aufrufst (was du ja tust) werden deine Listen nie initialisiert (Sind also null). Wenn du jetzt bspw mit einem Getter auf die Liste zugreifst und eine Methode darauf aufruft kracht es.
 
Oh, stimmt! Das habe ich ganz vergessen🙂

Ich werde, dass alles eh noch mal umschreiben, da FiLo später eine Library sein soll (die in anderen Projekten eingesetzt werden kann). D.h alles aus dem Konstrukter raus, und in Methoden packen.

Ich danke für eure Hilfe! Wenn neue Probleme auftreten melde ich mich🙂

Einen schönen Sonntag noch.
Florian
 
Bei der Klasse vielleicht schon. Aber bei etwas größeren Klassen wird der Code dadurch doch "strukturiert", und dies macht ihn ja lesbarer. Oder nicht?

(Man könnte ja eine Methode zum Lesen der ConfigFile und eine andere zum Schreiben in die Globale Variable erstellen)

Freundliche Grüße
Florian
 
..so es gibt ein weiteres Problem.
Ich habe ja insgesamt 3 Klassen (FiLo, ConfigurationFile und FilesAndDirectories)!
Ich rufe in jeder Klasse den Konstruktor FiLo() auf. Das Problem ist, dass dadurch immer eine neue Instanz von den beiden Listen (List<String>) erstellt wird. Denn ich muss ja in FiLo von jeder Klasse ein Objekt erstellen.

Wie kann man das Problem lösen. Denn der Wert in FiLo soll ja bleiben, sodass die Klasse: FilesAndDirectories auf die 2 Listen zugreifen kann.

P.S: Der Code der dritten Klasse:
Java:
package de.florian.filo;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
* FiLo - A tool for searching different Files and Folders
*
* Created by Florian Abeln on 14.06.2017.
*/

class FilesAndDirectories {
    private List<Path> path;

    FilesAndDirectories() {
        path = new ArrayList<>();

        FiLo filo = new FiLo();

        StringBuilder extensions = new StringBuilder();

        for(int i = 0; i < filo.getFileExtensions().size(); i++) {
            extensions.append(filo.getFileExtensions().get(i)).append(",");
        }

        extensions.insert(0, "*.{").insert((filo.getFileExtensions().size() + 1), "}");
        extensions.toString();
    }
}

Ich danke schon mal für die Hilfe 🙂
 
Du musst einen gescheiten Weg finden wie du deine Dependencies übergibst.
Mal dir auf nem Blatt auf wie die Klassen miteinander zusammen hängen und dann erstellst du dementsprechend die Objekte und übergibst sie in die jeweiligen Klassen.
 
Auf diese Idee bin ich gar nicht gekommen 🙂

Ich danke euch für die zahlreichen Antworten!

Freundliche Grüße
Florian

P.S. Damit hat sich das Problem und damit auch das Thema erledigt!
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben