简体   繁体   中英

Do you think I'm abusing of statics?

I'm new in Java programming and I think I have clear what are the objects and how to work with them.

However, now that I'm writing a program I have noticed that I have used a lot the 'static' keyword for methods, and I'm doubting if it is because it is really neccesary and logical or if it is because I have not internalized in my mind the OO concepts.

To be more specific, my program should read from a txt file and put each line in an ArrayList, this is my code:

public class FileBody {

    private static final String SEPARATOR = ";";
    private static String headerField1 = "regex";
    private static String headerField2 = "origin";
    private static String headerField3 = "destination";
    private static final String HEADER = headerField1 + SEPARATOR + headerField2
            + SEPARATOR + headerField3 + SEPARATOR;

    // Getters & setters

    public static String getHeader() {
        return HEADER;
    }

    public static String getHeaderField1() {
        return headerField1;
    }

    public static void setHeaderField1(String headerField1) {
        FileBody.headerField1 = headerField1;
    }

    public static String getHeaderField2() {
        return headerField2;
    }

    public static void setHeaderField2(String headerField2) {
        FileBody.headerField2 = headerField2;
    }

    public static String getHeaderField3() {
        return headerField3;
    }

    public static void setHeaderField3(String headerField3) {
        FileBody.headerField3 = headerField3;
    }

    // End getters & setters

    public static File createFileIfNotExists(String path) throws IOException {
        File file = new File(path);
        if (file.createNewFile());
        return file;
    }

    public static File getFile(String path) throws IOException {
        File file = createFileIfNotExists(path);
        return file;
    }

    public static boolean isEmpty(File file) throws Exception {
        FileReader fileReader = new FileReader(file);
        if (fileReader.read() != -1) {
            fileReader.close();
            return false;
        } else {
            fileReader.close();
            return true;
        }
    }

    public static void writeHeaderToEmptyFile(File file) throws Exception {
        if (isEmpty(file)) {
            BufferedWriter bufferedWriter = new BufferedWriter(
                    new FileWriter(file, false));
            bufferedWriter.write(HEADER);
            bufferedWriter.close();
        } else {
            return;
        }
    }

    public static ArrayList<String> getLines(File file) throws Exception {
        ArrayList<String> lines = new ArrayList<>();
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        while (bufferedReader.ready()) {
            lines.add(bufferedReader.readLine());
        }
        bufferedReader.close();
        return lines;
    }

}

Do you think I could have done it better with objects? If the answer is yes, could you give me the guidelines to do that?

Thank you very much for your help.

Having mutable static fields should be avoided where-ever possible. In particular, what you have won't work because they are only initalised once.

// only run once even if these fields are changed.
private static final String HEADER = headerField1 + SEPARATOR + headerField2
        + SEPARATOR + headerField3 + SEPARATOR;

Most likely what you want is

public static String getHeader() {
    return headerField1 + SEPARATOR + headerField2
        + SEPARATOR + headerField3 + SEPARATOR;
}

The only field which should be static is SEPARATOR as this is a constant. I would try to make all the other fields into non-static fields (and their getter/setters)

You have some utility/helper methods at the end of the class. I would put these in another class as they don't appear to be related. ie have a clear utility class for these methods instead. eg

class FileBody {
    public void writeHeaderToEmptyFile(File file) throws IOException {
        if (!FileUtils.isEmpty(file)) return
        try (Writer w = new FileWriter(file)) {
            w.write(getHeader());
        }
    }
}

class enum FileUtils {
    /* no instances */ ;

    // TODO replace all callers with new File(x);
    public static File getFile(String filename) { 
         return new File(filename);
    }

    public static boolean isEmpty(File file) {
        return file.length() > 0;
    }

    public static List<String> getLines(File file) throws Exception {
        return Files.readAllLines(Paths.get(file.getAbsolutePath()));
    }
}

Let's have a quick look at what you did right and wrong:

Right:

You kept your fields private and provided public methods to access that. +1 for that.

Wrong:

  1. You are keeping static fields private. Private fields can be accessed only from within the class (except in case of reflection: let's not go into that right now). So there is no added advantage you are gaining from marking it as static. Instead it will be an overhead in the memory (small in this case but still)

  2. If at all you want them as static, you should have not left them immutable. static fields are class level fields and not marking them as final, you are allowing different objects of your class to modify them which may lead to data corruption.

  3. Right now you are using Strings which have a separate memory management mechanism in Java. But if you use the same code with object references(marking object references as static), then you would be keeping your objects alive in memory for a long time unnecessarily which will be a huge strain on memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM