Java:作为控制stream的exception?

我听说使用控制stream的exception是不好的做法。 你觉得这怎么样?

public static findStringMatch(g0, g1) { int g0Left = -1; int g0Right = -1; int g1Left = -1; int g1Right = -1; //if a match is found, set the above ints to the proper indices //... //if not, the ints remain -1 try { String gL0 = g0.substring(0, g0Left); String gL1 = g1.substring(0, g1Left); String g0match = g0.substring(g0Left, g0Right); String g1match = g1.substring(g1Left, g1Right); String gR0 = g0.substring(g0Right); String gR1 = g1.substring(g1Right); return new StringMatch(gL0, gR0, g0match, g1match, gL1, gR1); } catch (StringIndexOutOfBoundsException e) { return new StringMatch(); //no match found } 

所以,如果没有find匹配,则整数将是-1。 这会导致一个exception,当我试图取的子stringg0.substring(0, -1) 。 然后该函数只是返回一个对象,指出没有find匹配。

这是不好的做法? 我可以手动检查每个索引,看看他们是否都是-1,但感觉像更多的工作。

UPDATE

我已经删除了try-catch块并将其replace为:

  if (g0Left == -1 || g0Right == -1 || g1Left == -1 || g1Right == -1) { return new StringMatch(); } 

哪一个更好:检查每个variables是否为-1,或者使用boolean foundMatch来跟踪,并在最后检查?

一般而言,例外是昂贵的操作,正如名称所示,特殊条件。 因此,在控制应用程序stream程的情况下使用它们确实被认为是不好的做法。

特别是在你提供的例子中,你需要对你提供给StringMatch构造函数的input做一些基本的validation。 如果这是一个返回一个错误代码的方法,如果一些基本的参数validation失败,你可以避免事先检查,但事实并非如此。

我已经做了一些testing。 在现代JVM上,它实际上不会影响运行时性能(如果有的话)。 如果在debugging开启的情况下运行,那么它确实会使速度变慢。

详情请参阅以下内容

(我还要提一下,即使不影响性能,我依然认为这是一个糟糕的做法,更重要的是,它反映了一个可能很差的algorithmdevise,这将难以testing)

是的,这是一个不好的做法,特别是当你有办法避免一个exception(试图索引它之前检查string的长度)。 try和catch块被devise为将“正常”逻辑从“exception”和错误逻辑中分离出来。 在你的例子中,你已经把“正常的”逻辑传播到exception/错误块(没有发现匹配不是例外)。 你也在滥用substring所以你可以利用它产生的错误作为控制stream。

程序stream程应尽可能直线(因为即使应用程序变得相当复杂),并使用标准的控制stream程结构。 触摸代码的下一个开发者可能不是你,并且(误)误解了你使用exception而不是条件来确定控制stream的非标准方式。

我现在在一些遗留的代码重构过程中对这个问题稍有不同。

我发现这个方法最大的问题是使用try / catch打破了正常的编程stream程。

在我正在处理的应用程序中(这与您所应用的示例不同),使用exception来在方法调用中传达给定结果(例如查找帐号而未find它)。 这会在客户端创build意大利面代码,因为调用方法(在非例外事件或正常用例事件期间)会在调用之前执行任何代码并进入catch代码块。 这在一些非常长的方法中重复了很多次,使得代码很容易被误读。

对于我的情况,一个方法应该返回一个值,而不是真正特殊的事件。 exception处理机制旨在在发生exception时采取另一种path(尝试从方法内部恢复,以便仍然可以正常返回)。

在我看来,如果你的try / catch块非常紧密,你可以做到这一点。 但我认为这是一个坏习惯,可能会导致代码很容易被误解,因为调用代码会将抛出的exception解释为“GOTO”types的消息,从而改变程序stream程。 我担心,虽然这个案子不属于这个陷阱,但是这样做往往会导致编码习惯导致我现在正在生活的噩梦。

而那个噩梦并不愉快。