【发布时间】:2010-12-19 21:15:52
【问题描述】:
我必须在构造函数中初始化文件对象并处理异常,使用throws 是否有效还是应该使用try/catch?
【问题讨论】:
我必须在构造函数中初始化文件对象并处理异常,使用throws 是否有效还是应该使用try/catch?
【问题讨论】:
在构造函数中抛出异常是可以的。我知道一些 Java 库类是这样做的(URI 只是一个例子)。我认为抛出异常比返回未知或无效状态的对象要好。
【讨论】:
URL 类除了糟糕的代码外,并不是一个很好的例子。例如,它的equals 方法将根据您是否连接到互联网等返回不同的值。(只是一方面,您的答案很好)
我认为在构造函数中抛出异常是一种优雅的方式来指示构造函数内部的错误情况。否则,您将不得不创建另一个初始化资源的函数,并在构造对象后调用该函数。
【讨论】:
当然可以,并且抛出异常实际上是我会做的(而不是在构造函数中吞下它)。您想让调用者知道发生了意外的事情,您不想返回未正确初始化的实例。也就是说,可能表明你在构造函数中做了太多事情。
【讨论】:
考虑一个构造函数,或者任何方法,都有一个契约。构造函数的约定非常简单——你给我(零个、一个或多个)参数,我会给你一个构造对象。好的做法是建议这个对象应该正确初始化其内部数据结构并保持不变,尽管语言本身并没有强制执行这一点。
如果由于某种原因构造函数不能遵守这个契约,那么它应该抛出一个异常。这可能是因为传递的参数(如果有)不可接受(前提条件失败)或某些外部问题(文件系统已满、堆耗尽、网络中断等)阻止了它。
【讨论】:
对我来说,这不是效率问题。
如果您可以对异常状态做出反应并且仍然创建有效或至少可用的对象,则在构造函数中处理它。
否则 - 如果对象不可用 - 将异常返回给调用者。在这种情况下,他将无法获得对象并且无法继续处理不可用/不一致的实例,这可能会在应用程序的其他一些角落产生错误。
【讨论】:
您当然可以(例如,FileOutputStream 可以)。
应该明智地从构造函数中抛出异常 - 确保自己清理干净。有时会在构造函数中抛出异常以确保 RAII 被持有。
【讨论】:
一般来说,在构造函数中只包含简单的逻辑是个好主意(例如,使用参数值设置私有字段)。并使用其他特殊的“组装者”、“准备者”或“工厂”设置您的对象。 get/set 方法也是如此——它们应该尽可能简单。
当然可以从构造函数中抛出异常。但这不是一个好习惯。
【讨论】:
我建议尝试/捕获,并从捕获中抛出有用的错误。这将使用户更好地了解您的应用程序出了什么问题。例如,您应该检查文件是否存在以及格式是否正确。
【讨论】:
您应该在构造函数中将对象置于安全状态,但假设您要打开一个不存在的文件(用于读取),抛出异常是唯一的方法。所以这取决于你实现的逻辑
【讨论】:
当然,它实际上在 Java 中被大量使用。例如,
public FileInputStream(String name)
throws FileNotFoundException
【讨论】:
一般来说,在构造函数中做繁重的工作是个坏主意:在许多语言中,无论如何,在构造过程中可以对异常做些什么都会受到限制。
【讨论】:
如果你关心构造函数中初始化的内容,我会选择“抛出”,我猜你会这样做。
如果你隐藏了异常,那以后可能会导致问题。
【讨论】: