Java 仅仅为了检查是否抛出了异常而尝试/捕获某个内容可以吗?

Java 仅仅为了检查是否抛出了异常而尝试/捕获某个内容可以吗?,java,exception,Java,Exception,仅仅为了查看此代码是否引发了特定的异常而尝试一些无用的东西,这是一种好方法吗? 我想在抛出异常时做一些事情,而不是做其他事情 try { new BigDecimal("some string"); // This do nothing because the instance is ignored } catch (NumberFormatException e) { return false; // OK, the string wasn't a well-for

仅仅为了查看此代码是否引发了特定的异常而尝试一些无用的东西,这是一种好方法吗?
我想在抛出异常时做一些事情,而不是做其他事情

try {  
    new BigDecimal("some string"); // This do nothing because the instance is ignored  
} catch (NumberFormatException e) {  
    return false; // OK, the string wasn't a well-formed decimal  
}  
return true;

有太多的先决条件需要测试,构造函数BigDecimal()总是检查它们,所以这似乎是最简单的方法。

通常,应该避免这种做法。但是,由于没有实用方法
isValidBigDecimal(..)
,所以这就是解决方法

正如Peter Tillemans在评论中所指出的,将此代码放在名为
isValidBigDecimal(..)
的实用方法中。因此,您的代码将不知道确定有效性的方法,您甚至可以稍后切换到另一种方法


Boris Pavlović建议使用第三方库(commons lang)来检查这一点。这里还有一个更有用的方法,每当我需要验证数字时,我都会使用它-
NumberUtils.isNumber(…)
这样做没有错;毕竟,某种其他语言的支持者喜欢说“道歉比请求许可更容易”,也就是说,等待失败并加以处理比完全避免失败更容易。在这种情况下,既然没有其他选择,那就去尝试吧。

如果你不喜欢这种方法,试着使用from。对于无效的输入
字符串
,它返回
null

性能可能不好,语法也不详细,但代码非常精确。检查和使用之间没有重复,这一直是一个大问题


(注意,这种特殊类型的字符串转换实际上是为了调试和内部配置。它不处理区域设置和其他面向人的考虑。在文件格式和有线协议中使用会对类使用的表示形式产生强烈的依赖性。)是的,这当然与“例外情况下的例外”这一实用程序员概念相矛盾,但您知道自己在做什么,所以没有问题,IMO

有两种已知的方法“检查”前提条件

伊丽尔:三思而后行

这种编码风格在调用或查找之前显式地测试前置条件。这种风格与EAFP方法形成对比,其特点是存在许多if语句

EAFP:请求原谅比允许更容易

这种常见的编码风格假设存在有效的键或属性,如果假设被证明为错误,则捕获异常。这种简洁快速的风格的特点是有许多尝试和例外的陈述。这种技术与许多其他语言(如C语言)所共有的LBYL风格形成对比

对于具有duck类型的语言,EAFP总是一个好主意


这显然取决于你想做什么。。。若您不确定要操纵的对象的类型,请使用EAFP。

对克里斯的答案进行评论: 我没有看到“超级内存泄漏”。没有对创建的BigDecimal的引用。一旦此方法完成,并且超出范围,对象就可以进行垃圾收集


当我们保存不再需要的引用时,会发生内存泄漏,因此无法对对象进行垃圾收集。

Try/Catch块不应用于逻辑。

当然,为什么不呢。这是我们检查客户指定的电子邮件地址是否正确格式化的方法:

try
{
    MailMessage m = new MailMessage(from, to, subject, body);
    return true;
}
catch(SmtpFailedRecipientsException ex)
{
    return false;
}
现在,人们可能会争论结构的性能或适当性,但他们忘记了简单性的权衡:

  • 上述代码将捕获.NET接受的确切数据格式。任何解析过电子邮件地址的人都会知道,正确格式的电子邮件地址结构有很多差异。这段代码保证以.NET喜欢的方式验证电子邮件地址结构,而不是我认为应该的方式
  • 异常捕获了多个用例,而不仅仅是基本数据结构的正确性。它将验证CC、BCC和TO字段中的多个用户,这开始变得难以处理手写代码

正如上面其他讨论的那样,这个代码最好抽象成单独的实用类,而不是混合在主代码中。

您必须考虑到<强>在JVM的时间和资源方面,异常对象的构建是昂贵的< /强>,因为它必须构造Struk Trace.< /P> 因此,您提出的是一种简单但耗费资源的解决问题的方法


因此,此解决方案是否可接受取决于您对该函数的使用以及您的效率要求。

+1,尤其是如果您将其封装在一个具有意义名称的漂亮小函数中!lie是ValidBigDecimal),因此当出现更好的技术时,它可以很容易地进行交换。当实现为C#扩展方法时,这种小实用方法非常方便。很高兴您询问了这一点。这意味着您认识到这种模式是要避免的,但您看不到其他选项+1这不是问题的答案,但您的示例是一个极好的内存泄漏。。。在某些情况下,exception可能被用作函数的返回,但您不应该忘记new的返回。@Martin:是的,您是对的。我不注意,认为是C++而不是java,有垃圾收集。有一个替代方案——写一个大的十进制校验器,如果传递的十进制无效,返回false。另见Boris的答复。通常,应该避免检查/should/be
是否(x==valid)doSomething
,以及格式
try x catch y
在catch块中发现一些逻辑(如返回false)。这样做的方法总是不止一种。@Erick:我想我得到了假装有点喜欢Python的结果