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();
}
}
上面的代码打算做一些事情,如果它正常,那么返回true;如果没有(发生错误),那么应该返回这个错误消息string。它可以用PHP实现,但不能用Java
编辑:期望不能出去,必须在这里处理。
当smth出错时,只需返回bool或抛出异常。将异常处理留给调用方。
在Java中是不可能的。相反,让例外情况发生。
既然你不想破例外出,你可以这样做。如果一切顺利,返回字符串"true"。如果发生错误,则返回错误消息。在方法签名中,生成返回类型字符串。这基本上是个糟糕的设计。
这当然是复制品。看看如何编写Java函数,返回多个数据类型的值?我当然希望还有其他的。
由于要求ScriptException不在您的方法之外转义:是否可以在回滚后引发其他异常以指示失败?一个标准的方案是将原始异常包装在一个类型的新异常中,该类型是调用方可以处理的。
你真的应该用throw ex;而不是return ex.getMessage();
TKAUSL肯定在爪哇是可能的:使用EDCOX1×3。请参阅下面的关于如何模仿PHP样式(以及它为什么是坏的)的答案,以及如何安全地使用Java 7尝试使用资源和异常。
不能返回多个类型,但可以重新设计,这样就不必返回。一些可能性:
不要返回错误消息。相反,引发或重新引发异常,并让调用者处理它。
创建一些可以封装成功和错误状态以及所有相关信息的类,并返回该类的实例。
我推荐选项1。您已经在处理一个异常,您可以看到它对IT错误处理的用途。没有理由让它停在那里,处理任何本地清理,然后继续向调用者报告。
一些仓促构建的例子,现在我又回到了键盘前,仅仅是为了说明概念,而不是为了详尽或必要地逐字使用:
清理,然后再冲洗:
public boolean test () throws javax.script.ScriptException {
try {
transaction.begin();
...
transaction.commit();
return true;
} catch (javax.script.ScriptException ex) {
transaction.rollback();
throw ex;
}
}
清除,然后根据需要重新引发其他异常类型:
public boolean test () throws MyGreatException {
try {
transaction.begin();
...
transaction.commit();
return true;
} catch (javax.script.ScriptException ex) {
transaction.rollback();
throw new MyGreatException(ex);
}
}
返回提供状态信息的对象(这只是一般思想的一个简单示例):
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;
}
}
然后:
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;
}
等。
我没有意识到,但这是一种事务处理方法,因此没有期望可以超出
@约翰,那么你必须选择选项2或者它的一些变体。您对返回值做了什么?这可能有助于缩小你的选择范围。我在打电话,否则我会输入一个好的选项2示例,抱歉。
调用者检查它的值,它不是真的,然后我们警告异常消息。
@Johnsmith可以也应该将异常抛出方法之外。您可以在方法内部捕获它,执行rollback(),然后重新引发异常以指示操作失败(并已回滚)。任何其他方法都是糟糕的设计。
^@Johnsmith正如Kayaman所说,注意到有时有问题的设计在一些一次性的小程序中是可以原谅的,或者当你面对别人的糟糕的约束时,你必须解决问题,但如果你处于一个适度严肃的开发环境中,并且完全控制你所做的设计选择,就不能这样做。:)
不要归还任何东西。在您回滚后重新抛出原始异常。
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的方法。
// Helper class
class Pair{
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 returnSomething(){
try {
return new Pair(true,null);
}catch(Exception e){
return new Pair(false,e.getMessage());
}
}
// Calling this method would look like this
Pair result = returnSomething();
// Retrieve status
boolean status = result.getFirst();
// Retrieve error message (This is null if an exception was caught!)
String errorMessage = result.getSecond();
难看的胜利(但这个答案的第一部分让你难看,哈)!+ 1
是的,它是我在stackoverflow上挣扎时发布的。
如果您坚持,您可以退回Object。在这种情况下,true将自动发送到Boolean.TRUE。当然不建议这样做,这样会给调用者带来额外的麻烦,让他们弄清楚返回的对象是String还是Boolean。更糟的是,调用者不保证返回类型仅限于上述两种类型,但还应考虑到它可能是另一个类。
更好的选择取决于情况,所以我可能无法告诉你什么是最好的。有几个想法浮现在脑海中,但请不要不加批判地使用:(1)返回String,并返回null,而不是真正的成功。(2)设计自己的返回类;例如,它可以同时包含布尔值和消息字符串。
在您的情况下,应该使用异常,而不是隐藏异常。这不是结果,而是错误。了解如何在事务中处理异常!
函数编程FANBOOS将提倡一个单元格式结构,正如您可以在Java 8的EDCOX1×0 API中发现的那样。
也就是说,您可以返回Optional并在成功时(如果您没有return false和return true的话)不进行设置。
为了清晰起见,最好用自定义类来构建类似这样的内容:
interface Result {}
class BooleanResult implements Result {
boolean result;
public boolean getResult() { return result; }
}
class ErrorResult implements Result {
Exception cause;
public Exception getCause() { return cause; }
}
您可以使用null值模拟Optional(如果只有一个布尔结果)。成功后,返回null。非空值表示错误。
String perform() {
try{
...
return null; // No error
} except(Exception e) { // bad code style
return e.getMessage(); // Pray this is never null
}
}
String err = perform();
if (err != null) { throw up; }
类似的API在旧的C库中相当常见。除0以外的任何返回值都是错误代码。成功后,结果将写入方法调用时提供的指针。
你可以使用Object。
public Object perform() {...}
Object o = perform();
if (o instanceof Boolean) { ...
这是80年代的编程风格。这就是PHP所做的,所以在爪哇是可行的!这很糟糕,因为它不是一个安全的lpnger类型。这是最糟糕的选择。
我建议你试试1,3,2,4,5。在这个偏好中。或者更好,只考虑选项1和3。
至于选项1。你真的应该学习如何使用Try with Resources。您的交易是一种资源。
如果操作正确,代码将如下所示:
try(Transaction a = connection.newTransaction()) {
doSomethingThatMayFail(a);
a.commit();
} // No except here, let try handle this properly
即使发生异常,Java也会调用EDCOX1 8Ω。然后它将向上抛出异常。sour事务类应该有这样的代码来处理回滚:
public void close() {
if (!committed) rollback();
}
这是最优雅、最短、最安全的方法,因为Java确保调用EDOCX1 9Ω。抛出异常,然后正确地处理它。上面显示的代码截图是反模式的,并且很容易出错。
Exceptions can't go outside, it has to be handled here.
我必须说,这种限制只能使接口更难使用。假设您希望返回一些内容,以便调用方检查此方法中是否发生异常,而调用方可以忽略返回的值,无论发生什么。所以我想你应该给来电者一些灵活性:如果可能的话,他/她不需要为最终的结果操心。但是使用异常方法,调用者仍然可以这样做,使用空的(不推荐)catch子句。
例外是最好的方法。除非"外部"是不支持异常的环境。然后你别无选择,只能在scala中想出类似于Try的东西。
如果您使用Java 8,则可以返回EDCOX1 OR 1。然后,如果代码成功,则返回一个空的可选代码;如果出现故障,则返回一个包含故障消息的可选代码。