【问题标题】:java exception handling in constructor构造函数中的java异常处理
【发布时间】:2011-05-16 14:52:16
【问题描述】:

老实说,我对异常处理不是很有经验,因为经常因为我的懒惰,我倾向于不处理异常。所以这是一个非常基本的问题。

我想知道用异常处理方法来完成这种情况的最干净的方法是什么:

我有一个类(ConfigManager),它在其构造函数中读取一个文件,并且需要该文件存在才能正确构造,作为构造函数参数给出。 如果该文件不存在,我想捕获 FileNotFoundException,使用一些默认值创建该文件,然后使用现在可用的默认配置文件继续创建 ConfigManager 对象。

这里有一些代码:

class ConfigManager{
    ConfigManager(String file){
         try{
             builder = builderFactory.newDocumentBuilder();
             document = builder.parse (new FileInputStream(file));
             ....
         }catch (FileNotFoundException e) {

        File configFile =  new File (file);

        try {

            configFile.createNewFile();
            BufferedWriter writer = new BufferedWriter(new FileWriter(configFile));
            writer.write(this.defaultConfig);
            writer.close();


            return new ConfigManager(string); //Here's the problem. I can't do that but I need to try build ConfigManager again. How do that?

        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}  

在创建默认配置文件后,如何构造一个新的 ConfigManager 对象? 这是处理此类异常的正确方法吗?

提前致谢

【问题讨论】:

  • 第一个catch之后是否缺少一些代码?
  • 我认为在这种情况下最好让构造函数抛出异常(即不在构造函数中处理它)。提供另一个不带 File 参数的构造函数来创建默认管理器。

标签: java file-io constructor exception-handling filenotfoundexception


【解决方案1】:

您可以做的是在尝试解析文件之前确保文件存在。

FileInputStream fis = null;
try {
    fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
    BufferedWriter writer = new BufferedWriter(new FileWriter(configFile));
    writer.write(defaultConfig);
    writer.close();
    fis = new FileInputStream(file);
}

try{
     builder = builderFactory.newDocumentBuilder();
     document = builder.parse (fis);

【讨论】:

    【解决方案2】:

    不要在构造函数中读取文件,创建一个方法(可能是私有的)来读取文件并在 ConfigManager 上设置值。

    然后在构造函数中,尝试再次调用构造函数,只需调用方法即可。

    即不要再次调用构造函数。

    更新——我会这样组织代码:

    ConfigManager(String fileName) {
       File file = new File(fileName);
       if (!file.exists()){
           // create this method -- Im assuming its ok to put the default 
           // config on the path where the file did not exist.
           createDefaultConfigFile(fileName); 
       }
    
       parseConfigFile(fileName, ...); // create this method too
    }
    

    这显然不是工作代码,我不知道具体你在做什么,所以尽我所能。但它比您现在拥有的更具可读性,并且更有条理。另外,如果指定的配置文件不存在,您真的要创建一个新的默认配置文件吗?为什么不弹出警告说配置不存在,所以您使用默认值,但不写入默认文件?您可能有理由编写默认值,如果这是真的,那么可以,但如果您不需要,请不要添加更多工作......

    【讨论】:

      【解决方案3】:

      解决方案是将构造函数分成两部分。第一部分尝试从现有文件创建FileInputStream。如果它抛出FileNotFoundException,那么您如上所述创建并填充文件,然后再次打开FileInputStream。第二部分获取第一部分打开的文件FileInputStream(不管它是如何打开的)并继续初始化。

      另一种选择是将此加载推迟到 init() 方法,以便您的类的使用者必须创建和初始化他们的对象。

      【讨论】:

        【解决方案4】:

        您需要能够再次调用构造函数,但无需创建新对象 - 只需在同一个对象上调用它。由于 Java 不允许您这样做,因此您必须创建一个辅助方法,将代码从构造函数移到该方法中,然后从构造函数调用新方法。

        这是一种基本技术,适用于需要实现递归但不能直接递归的任何情况。

        【讨论】:

          【解决方案5】:

          实现这一点的最简洁的方法是不执行任何可能导致构造函数异常的操作。如果您在使用对象之前绝对需要执行它们,请在单独的方法 init() 中执行它们。

          【讨论】:

            【解决方案6】:

            尝试将配置文件的解析委托给另一种方法。这样,您可以先检查文件是否存在,然后创建一个默认文件,或者将现有文件传递给这个新方法。

            【讨论】:

              【解决方案7】:

              好吧,实际上,在构造函数执行后没有错误,您有一个新的 ConfigManager 实例。所以你所要做的就是删除有问题的行。

              或者考虑使用静态初始化器。当您的应用程序部署/启动时,这将只检查一次文件。

              【讨论】:

                【解决方案8】:

                通常因为我的懒惰,我倾向于不 处理异常

                我建议你先解决懒惰。实际上,您只是在为自己创造更多的工作。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-01-08
                  • 1970-01-01
                  • 2020-12-04
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多