2016-03-17 29 views
0

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

} 

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

非常感谢您的帮助。

+2

你应该问问自己,你应该怎么用FileBody类来表示多个文件体。 – Eran

+0

确切地说,您只能拥有一个文件实例 –

+0

不要打扰手动关闭资源 - 请尝试使用资源。它不那么冗长,也不太容易出错。 –

回答

4

可变静态字段应尽可能避免。特别是,你有什么将不会工作,因为他们只有一次初始化。

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

这应该是staticSEPARATOR,因为这是一个不变的唯一领域。我会尝试将所有其他字段设置为非静态字段(以及它们的getter/setter)

您在类的结尾处有一些实用程序/辅助方法。我会把它们放在另一个班,因为它们看起来没有关系。即对于这些方法而言具有明确的实用程序类别。例如

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

感谢您的解释和例子,他们非常有帮助。我会照你说的去做。 – Arcones

0

让我们快速浏览一下你做了什么对与错:

右:

你保持你的私人领域和提供的公共方法来访问。 +1。

错误:

  1. 你保持静态字段私有。私人领域只能从课堂内部进行访问(除了反思的情况:我们现在不进入)。因此,将其标记为静态不会带来额外的好处。相反,它将成为内存开销(在这种情况下小,但仍然)

  2. 如果根本就想让它们成为静态,那么应该不会让它们不可变。静态字段是类级别字段,不会将它们标记为最终字段,您允许类的不同对象修改它们,这可能会导致数据损坏。

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

+0

非常感谢您告诉我这些概念。你能否给我进一步的细节:“私人领域只能从课堂上进行访问,所以没有任何额外的好处,你可以将其标记为静态。”我知道“私人”关键作品的范围,这就是公开进行获取者和制作者的原因,但我不太了解你为什么说他们没有增加静态的优势?你能举个例子吗? – Arcones

+0

好的。只要内存中加载了一个类,静态对象就会保留在内存中(或者您可以说在程序的整个持续时间内)。所以当你使用静态字段时你会阻止你的记忆(见第3点以获得更多的参考)。所以他们必须吝啬使用。 – theLearner