在Java中链接构造函数而不从默认构造函数中抛出异常

时间:2011-08-19 18:29:18

标签: java exception constructor constructor-chaining

我读过这个:Can I use throws in constructor? - 它给了我正确的想法,并引导我一个答案,但不是很明确。我也读过其他几个,但找不到我的答案。回顾一下我为上下文学到的东西,基本上,这不会编译......

public ExampleClass(String FileName)
{
   this(new FileInputStream(FileName));
}

public ExampleClass(FileInputStream FileStream)
{
   DoSomethingToSetupBasedUponFileStream(FileStream);
}

...因为FileInputStream构造函数(从字符串构造函数调用)可能会抛出FileNotFoundException。您仍然可以通过使抛出相同的异常来创建构造函数,如下所示:

public ExampleClass(String FileName) throws FileNotFoundException
{
   this(new FileInputStream(FileName));
}

我的问题与默认构造函数(无参数)有关,它只使用默认文件名字符串常量:

public ExampleClass() throws FileNotFoundException
{
   this(DEFAULT_FILE_NAME);
}

这会将构造函数链接为:

ExampleClass() - &gt; ExampleClass(<String>) - &gt; ExampleClass(<InputFileStream>)

在这种情况下,是否可以在默认构造函数中使用默认值(静态最终类成员)来实例化(进一步向下)链接FileInputStream,但不必使用{{ 1}}代码(需要有人使用该类重新抛出或处理异常?

如果我可以做类似以下的事情,我会自己处理这个例外:

throws FileNotFoundException

...但是,据我所知这是不可能的,因为“构造函数调用必须是构造函数中的第一个语句”

此时更习惯.Net,如果我真的不想......我就没有强迫来处理异常:D

4 个答案:

答案 0 :(得分:2)

从你的构造函数中重构你的文件构造代码,所以你可以做这样的事情 -

public ExampleClass() {
  try {
      fileInputStreamMethod(DEFAULT_FILE);
  }
  catch(Exception e) {
    ...
  }

public ExampleClass(String fileName) throws Exception {
    fileInputStreamMethod(fileName);
}

private void fileInputStreamMethod(String fileName) throws Exception {
    // your file handling methods
}

答案 1 :(得分:0)

你是对的,你不能从对此(...)的调用中捕获异常。

您可以使用静态方法生成您想要的内容:

static ExampleClass createDefault()
{
  try
  {
    return new ExampleClass(DEFAULT_FILE_NAME);
  }
  catch(Exception e)
  {
    DoSomethingToHandleException(e)
  } 
}

答案 2 :(得分:0)

你可以这样做:

public ExampleClass(String FileName)
{
   this(getStream(FileName));
}

private static FileInputStream getStream(String name) {
    try {
        return new FileInputStream(name);
    } catch (Exception e) {
        // log error
        return null;
    }
}

真正的问题是,为什么想要抛出异常?如果无法打开文件,您的程序应该如何运作?我认为你希望它继续进行就好像没有问题一样是不寻常的。很可能,null输入流将在以后引起悲伤。

一般情况下,最好尽可能靠近错误来源抛出异常。

答案 3 :(得分:0)

基本上你要做的是做一个构造函数必须在另一个方法中做的工作(不是构造函数),然后在默认构造函数中使用它。但我不确定这种技术在你的场景中有多大用处。

喝彩!