我写了七个测试用例来理解finally
块的行为.如何finally
运作背后的逻辑是什么?
package core;
public class Test {
public static void main(String[] args) {
new Test().testFinally();
}
public void testFinally() {
System.out.println("One = " + tryOne());
System.out.println("Two = " + tryTwo());
System.out.println("Three = " + tryThree());
System.out.println("Four = " + tryFour());
System.out.println("Five = " + tryFive());
System.out.println("Six = " + trySix());
System.out.println("Seven = " + trySeven());
}
protected StringBuilder tryOne() {
StringBuilder builder = new StringBuilder();
try {
builder.append("Cool");
return builder.append("Return");
}
finally {
builder = null; …
Run Code Online (Sandbox Code Playgroud) 是否需要以下结构?
using (Something something = new Something())
{
try
{
}
finally
{
something.SomeCleanup();
}
}
Run Code Online (Sandbox Code Playgroud)
或者,是否应在隐式调用中执行所有清理任务something.Dispose()
?
这是违规代码:
public static DataTable GetDataTable(string cmdText, IEnumerable<Parameter> parameters)
{
// Create an empty memory table.
DataTable dataTable = new DataTable();
// Open a connection to the database.
using (SqlConnection connection = new SqlConnection(ConfigurationTool.ConnectionString))
{
connection.Open();
// Specify the stored procedure call and its parameters.
using (SqlCommand command = new SqlCommand(cmdText, connection))
{
command.CommandType = CommandType.StoredProcedure;
SqlParameterCollection parameterCollection = command.Parameters; …
Run Code Online (Sandbox Code Playgroud) 我试图绕过这个.根据此页面上的Using
发言:
using语句确保即使在对象上调用方法时发生异常,也会调用Dispose.您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果; 实际上,这就是编译器如何翻译using语句.
在处理的异常中,保证运行关联的finally块.但是,如果未处理异常,则finally块的执行取决于如何触发异常展开操作.
那么如果一个Using
语句转换Try-Finally
为不能保证调用finally语句的语句,如何在异常情况下保证调用Dispose方法?
我正在使用尝试/最后在Powershell中编写监视脚本,以在脚本结束时记录消息。该脚本旨在无限期运行,因此我想要一种跟踪意外退出的方法。
我检查过的所有其他StackOverflow发布和帮助页面都指出:
即使您使用CTRL + C来停止脚本,Final块也会运行。如果Exit关键字从Catch块中停止脚本,则Final块也将运行。
实际上,我还没有发现这是真的。我正在使用以下人为设计的示例进行测试:
Try {
While($True) {
echo "looping"
Start-Sleep 3
}
} Finally {
echo "goodbye!"
pause
}
Run Code Online (Sandbox Code Playgroud)
无论是作为保存的脚本运行还是通过内置Powershell ISE执行时,Finally
每次在Ctrl+ C(无回声,无暂停)之后都将跳过此处的块。我得到的唯一输出是:
looping
looping
...(repeat until Ctrl-C)
Run Code Online (Sandbox Code Playgroud)
我显然错过了一些东西,但是我不知道它是什么,尤其是在这么小的代码片段中。
在新的第三版Effective Java中,Joshua Bloch提到了Java Puzzlers的一段代码(它是关于在try-finally中关闭资源):
对于初学者来说,我在Java Puzzlers的第88页上弄错了,多年来没有人注意到.事实上,2007年Java库中close方法的三分之二使用是错误的.
但我不确定哪个部分错了?
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
if (out != null) {
try {
out.close();
} catch (IOException ex) {
// Again, there is nothing we can do if close fails
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是此代码的新版本:
try {
OutputStream out = new FileOutputStream(dst);
try {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while …
Run Code Online (Sandbox Code Playgroud) 我试图理解当我最终在while循环中使用时的机制.在下面的代码中.在最后的行打印和比休息时间.我期待代码不会到达finally块.或者,如果它到达finally块,那里就没有中断,所以while应该继续..任何人都可以解释这是如何工作的?
while(true){
System.out.println("in while");
try{
break;
}finally{
System.out.println("in finally");
}
}
System.out.println("after while");
Run Code Online (Sandbox Code Playgroud)
输出是
in while
in finally
after while
Run Code Online (Sandbox Code Playgroud) try
{
try
{
throw new Exception("From Try");
}
catch
{
throw new Exception("From Catch");
}
finally
{
throw new Exception("From Finally");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Run Code Online (Sandbox Code Playgroud)
上面代码的输出是:From Finally
.
为什么不From Catch
呢?
-要么-
我怎样才能从外部捕获和记录两个例外?
可能重复:
在finally块中抛出异常
只有在try块中抛出异常时才会执行catch块.
如果抛出异常,则始终在try(-catch)块之后执行finally块.
我的问题是,如果我在finally块中得到Exception而不是如何处理它?????
我有一个简单的问题,一个简单的代码部分,一些基本的try-finally
块:
try {
// Some code which can throw an Exception
} finally {
// Some code which also can throw an Exception
}
Run Code Online (Sandbox Code Playgroud)
我的主要问题是:我们有什么方法可以发现是否在finally
块中抛出异常而不使用catch
和一些局部变量在块之间传递信息?
我几乎没有什么情况可以使用,我不想添加一些丑陋的不必要的catch
块来设置一些变量throw Exception
.第一个例子是,如果我在某些Spring或容器管理的事务方法中,并且在try
块中Exception
发生了.finally
在这种情况下,我需要创建新的事务来处理数据库.第二个例子是我不希望我的原始Exception
被块Exception
抛出掩盖finally
,但如果没有Exception
我会抛出它finally
(如果有的话).
我知道这一切都可以完成,catch
但有没有其他方式,Java中的一些元数据或其他任何东西?如果我们可以假设这将在一个中执行Thread
,那么它可能会有所帮助,所以也许有一些方法可以发现与当前有关的异常Thread
?
当我尝试在Java中执行以下函数时:
public static int myfunc (int x) {
try {
return x;
} finally {
x++;
}
}
public static void main (String args[]) {
int y=5,z;
z = myfunc(y);
System.out.println(z);
}
Run Code Online (Sandbox Code Playgroud)
控制台上打印的输出为5,可以预期打印6.知道为什么吗?
try-finally ×10
java ×6
.net ×2
c# ×2
try-catch ×2
using ×2
break ×1
exception ×1
finally ×1
powershell ×1
while-loop ×1