你认为我在滥用静电吗?

Do you think I'm abusing of statics?

我是 Java 编程新手,我想我已经清楚对象是什么以及如何使用它们。

但是,现在我正在编写一个程序,我注意到我在方法中使用了很多 'static' 关键字,我怀疑这是不是因为它真的是必要的和合乎逻辑的,或者如果是因为我没有在脑海中内化面向对象的概念。

更具体地说,我的程序应该从一个 txt 文件中读取并将每一行放在一个 ArrayList 中,这是我的代码:

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;
    }

}

你认为我可以用对象做得更好吗?如果答案是肯定的,你能给我指导方针吗?

非常感谢您的帮助。

可变静态字段应尽可能避免。特别是,您所拥有的将无法使用,因为它们只初始化了一次。

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

很可能你想要的是

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

唯一应该是 static 的字段是 SEPARATOR,因为这是一个常量。我会尝试将所有其他字段变成非静态字段(及其 getter/setters)

您在 class 末尾有一些 utility/helper 方法。我会把它们放在另一个 class 中,因为它们似乎没有关系。也就是说,这些方法有一个明确的实用程序 class。例如

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()));
    }
}

让我们快速看看你做对了什么和做错了什么:

右:

您将您的字段保密并提供了 public 方法来访问它。 +1。

错误:

  1. 您将静态字段保密。私有字段只能从 class 中访问(反射情况除外:我们现在先不谈)。因此,将其标记为静态不会带来额外的好处。相反,它将是内存中的开销(在这种情况下很小但仍然)

  2. 如果您完全希望它们是静态的,您不应该让它们保持不变。静态字段是 class 级别字段并且没有将它们标记为最终字段,您允许 class 的不同对象修改它们,这可能会导致数据损坏。

  3. 现在您使用的字符串在 Java 中具有单独的内存管理机制。但是,如果您对对象引用使用相同的代码(将对象引用标记为静态),那么您将不必要地使对象在内存中长时间保持活动状态,这将对内存造成巨大压力。