Java, what if I want to return different types from function?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public WHATTOWRITEHERE test() { try { transaction.begin(); code which may trigger exception transaction.commit(); return true; } catch (javax.script.ScriptException ex) { transaction.rollback(); return ex.getMessage(); } } |
上面的代码打算做一些事情,如果它正常,那么返回
编辑:期望不能出去,必须在这里处理。
不能返回多个类型,但可以重新设计,这样就不必返回。一些可能性:
我推荐选项1。您已经在处理一个异常,您可以看到它对IT错误处理的用途。没有理由让它停在那里,处理任何本地清理,然后继续向调用者报告。
一些仓促构建的例子,现在我又回到了键盘前,仅仅是为了说明概念,而不是为了详尽或必要地逐字使用:
清理,然后再冲洗:
1 2 3 4 5 6 7 8 9 10 11 | public boolean test () throws javax.script.ScriptException { try { transaction.begin(); ... transaction.commit(); return true; } catch (javax.script.ScriptException ex) { transaction.rollback(); throw ex; } } |
清除,然后根据需要重新引发其他异常类型:
1 2 3 4 5 6 7 8 9 10 11 | public boolean test () throws MyGreatException { try { transaction.begin(); ... transaction.commit(); return true; } catch (javax.script.ScriptException ex) { transaction.rollback(); throw new MyGreatException(ex); } } |
返回提供状态信息的对象(这只是一般思想的一个简单示例):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class TransactionResult { private final boolean failed; private final String reason; /** Construct a result that represents a successful transaction. */ public TransactionResult () { failed = false; reason = null; } /** Construct a result that represents a failed transaction with a reason. */ public TransactionResult (String failedReason) { failed = true; reason = failedReason; } public boolean isFailed () { return failed; } public String getReason () { return reason; } } |
然后:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public TransactionResult test () { TransactionResult result; try { transaction.begin(); ... transaction.commit(); result = new TransactionResult(); } catch (javax.script.ScriptException ex) { transaction.rollback(); result = new TransactionResult(ex.getMessage()); } return result; } |
等。
不要归还任何东西。在您回滚后重新抛出原始异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public void test() { try { transaction.begin(); code which may trigger exception transaction.commit(); } catch (javax.script.ScriptException ex) { transaction.rollback(); throw ex; // re-throw the original exception } } |
丑陋的解决方法,但是如果您真的想这样做,您可以始终定义一个包装状态和错误消息的助手类,但是我更喜欢@jsonc的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // Helper class class Pair<First,Second>{ private First first; private Second second; Pair(First first,Second second){ this.first = first; this.second = second; } public First getFirst(){ return this.first; } public First getSecond(){ return this.second; } } // Function returning two types public Pair<boolean,String> returnSomething(){ try { return new Pair<boolean,String>(true,null); }catch(Exception e){ return new Pair<boolean,String>(false,e.getMessage()); } } // Calling this method would look like this Pair<String,boolean> result = returnSomething(); // Retrieve status boolean status = result.getFirst(); // Retrieve error message (This is null if an exception was caught!) String errorMessage = result.getSecond(); |
如果您坚持,您可以退回
更好的选择取决于情况,所以我可能无法告诉你什么是最好的。有几个想法浮现在脑海中,但请不要不加批判地使用:(1)返回
在您的情况下,应该使用异常,而不是隐藏异常。这不是结果,而是错误。了解如何在事务中处理异常!
函数编程FANBOOS将提倡一个单元格式结构,正如您可以在Java 8的EDCOX1×0 API中发现的那样。
也就是说,您可以返回
为了清晰起见,最好用自定义类来构建类似这样的内容:
您可以使用
1 2 3 4 5 6 7 8 9 10 11 |
类似的API在旧的C库中相当常见。除0以外的任何返回值都是错误代码。成功后,结果将写入方法调用时提供的指针。
你可以使用
这是80年代的编程风格。这就是PHP所做的,所以在爪哇是可行的!这很糟糕,因为它不是一个安全的lpnger类型。这是最糟糕的选择。
我建议你试试1,3,2,4,5。在这个偏好中。或者更好,只考虑选项1和3。
至于选项1。你真的应该学习如何使用Try with Resources。您的交易是一种资源。
如果操作正确,代码将如下所示:
1 2 3 4 | try(Transaction a = connection.newTransaction()) { doSomethingThatMayFail(a); a.commit(); } // No except here, let try handle this properly |
即使发生异常,Java也会调用EDCOX1 8Ω。然后它将向上抛出异常。sour事务类应该有这样的代码来处理回滚:
1 2 3 | public void close() { if (!committed) rollback(); } |
这是最优雅、最短、最安全的方法,因为Java确保调用EDOCX1 9Ω。抛出异常,然后正确地处理它。上面显示的代码截图是反模式的,并且很容易出错。
Exceptions can't go outside, it has to be handled here.
我必须说,这种限制只能使接口更难使用。假设您希望返回一些内容,以便调用方检查此方法中是否发生异常,而调用方可以忽略返回的值,无论发生什么。所以我想你应该给来电者一些灵活性:如果可能的话,他/她不需要为最终的结果操心。但是使用异常方法,调用者仍然可以这样做,使用空的(不推荐)catch子句。
例外是最好的方法。除非"外部"是不支持异常的环境。然后你别无选择,只能在scala中想出类似于
如果您使用Java 8,则可以返回EDCOX1 OR 1。然后,如果代码成功,则返回一个空的可选代码;如果出现故障,则返回一个包含故障消息的可选代码。