哪两个是创建和销毁对象的更好方法?

时间:2012-05-16 05:06:12

标签: java

我对第26行和第26行有疑问。 27:

String dumb = input.nextLine();
output.println(dumb.replaceAll(REMOVE, ADD));

我希望我能够将它缩小到单行,并且能够节省空间,所以我做了:

output.println(new String(input.nextLine()).replaceAll(REMOVE, ADD));

但现在我对性能感到疑惑。我知道这个程序基本安静,不需要优化,但我想学习这个 我看待它的方式,在第一个场景中,我正在创建一个字符串对象哑,但是一旦我离开循环,对象就会被抛弃,JVM应该清理它,对吧?但是JVM是否比程序通过循环更快地清理被抛弃的对象?或者,一旦程序完成,会有几个字符串对象等待垃圾收集吗?

并且我的逻辑是正确的,在第二种情况下,String对象是动态创建的,并在程序通过该行后被销毁?这实际上是性能提升吗?

如果你能为我解决这个问题,我会很感激。

谢谢,

P.S。如果你想知道程序(我认为它是直接的)它接收一个输入文件,输出文件和两个单词,程序获取输入文件,用第二个单词替换第一个单词并将其写入第二个档案。如果你真的已经阅读了这篇文章,并希望建议我可以使我的代码更好的方法,请这样做。我会非常感激的。

import java.io.File;
import java.util.Scanner;
import java.io.PrintWriter;

public class RW {

    public static void main(String[] args) throws Exception{
        String INPUT_FILE = args[0];
        String OUTPUT_FILE = args[1];
        String REMOVE = args[2];
        String ADD = args[3];

        File ifile = new File(INPUT_FILE);
        File ofile = new File(OUTPUT_FILE);

        if (ifile.exists() == false) {
            System.out.println("the input file does not exists in the current folder");
            System.out.println("please provide the input file");
            System.exit(0);
        }

        Scanner input = new Scanner(ifile);
        PrintWriter output = new PrintWriter(ofile);

        while(input.hasNextLine()) {
            String dumb = input.nextLine();
            output.println(dumb.replaceAll(REMOVE, ADD));
        }
        input.close();
        output.close();


    }
}

3 个答案:

答案 0 :(得分:3)

我要说的第一件事就是:

不要担心过早地优化性能。 Java编译器很聪明,它会为你优化很多这样的东西,即使它没有你优化非常小的时间。您已经到达的流IO已经运行了比您正在谈论的时间长几个数量级。

最重要重要的是代码易于理解。你有一个很好的代码风格,从你的例子开始,所以保持这个。对于以外的其他人来说,哪两个代码段更容易阅读? 是最好的选择。 :)

尽管如此,这里有一些更具体的问题答案:

  1. 垃圾收集绝对会获取在循环范围内实例化的对象。它在循环中实例化的事实意味着Java一旦超出范围就已经标记了它以进行清理。 GC下次运行时,它将清理所有标记为清理的东西。

  2. 创建对象内联仍将创建一个对象。构造函数仍然被调用,内存仍然被分配......在引擎盖下,它们真的非常相似。只是在一种情况下,对象具有名称,而在另一种情况下,它不具有名称。您不会通过将两行代码合并为一行来保存任何实际资源。

  3. “input.nextLine()”已经返回一个String,因此您不需要将其包装在新的String()中。 (所以是的,删除实际导致实例化少一个对象!)

答案 1 :(得分:1)

本地对象一旦超出范围,就有资格使用GC。这并不意味着GC会在那个时刻清理它们。符合条件的对象经历了生命周期。 GC可能会也可能不会立即收集它们。

就你的程序而言,除了一两行之外没有什么可以优化的。以下是重组程序。

import java.io.File;
import java.util.Scanner;
import java.io.PrintWriter;

public class Test {
    public static void main(String[] args) throws Exception {
        String INPUT_FILE = args[0];
        String OUTPUT_FILE = args[1];
        String REMOVE = args[2];
        String ADD = args[3];

        File ifile = new File(INPUT_FILE);
        File ofile = new File(OUTPUT_FILE);
        if (ifile.exists() == false) {
            System.out.println("the input file does not exists in the current folder\nplease provide the input file"); 
            System.exit(0);
        }
        Scanner input = null;
        PrintWriter output = null;
        try {
            input = new Scanner(ifile);
            output = new PrintWriter(ofile);
            while (input.hasNextLine()) {
                output.println(input.nextLine().replaceAll(REMOVE, ADD));
            }
        } finally {
            if (input != null)
                input.close();
            if(output != null)
                output.close();
        }
    }
}

答案 2 :(得分:1)

如果您担心obejct创建和性能,请使用分析器来确定您的代码。请记住,执行new String(input.nextLine())完全没有意义,因为input.nextLine()返回String的不可变实例。所以只需output.println(input.nextLine().replaceAll(REMOVE, ADD));