java 在 Intellij 中,如何在断点处抛出异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17094304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Intellij, how can I throw an exception at a break point?
提问by Daniel Kaplan
I see lots of questions about how to make Intellij break on exceptions. I'm trying to do something different: I want to throw an exception at a breakpoint so that I can see what will happen if an exception were to occur at that code.
我看到很多关于如何让 Intellij 中断异常的问题。我正在尝试做一些不同的事情:我想在断点处抛出异常,以便我可以看到如果在该代码处发生异常会发生什么。
I've figured out ways to force this. For example, if I have a variable called willBeUsed
, I can hit a breakpoint and add a watch that says willBeUsed = null
. This will trigger a NullPointerException eventually.
我已经想出了强制执行此操作的方法。例如,如果我有一个名为 的变量willBeUsed
,我可以点击断点并添加一个显示willBeUsed = null
. 这最终将触发 NullPointerException 。
But I'm in a situation where I want to throw an IOException
to see what happens. There's no way to trick my code into doing that. When I add a watch that says throw new IOException()
it gives me an error saying, "unexpected tokens".
但是我处于一种情况,我想抛出一个IOException
来看看会发生什么。没有办法欺骗我的代码这样做。当我添加一个手表时,throw new IOException()
它说它给了我一个错误,说“意外的令牌”。
As a work around, I can modify the code to throw the exception and redeploy. But I'm wondering if there's a way to do this in the debugger without modifying source code.
作为一种变通方法,我可以修改代码以抛出异常并重新部署。但我想知道是否有一种方法可以在不修改源代码的情况下在调试器中执行此操作。
采纳答案by Marek F
You can right-click on stacktrace and choose 'Throw Exception'
您可以右键单击堆栈跟踪并选择“抛出异常”
(Since 2018.1 version. See JetBrains issue: IDEA-148408)
(自 2018.1 版本起。参见 JetBrains 问题:IDEA-148408)
回答by MByD
How about placing the throw
statement in an if
block, and only change the condition, e.g.:
如何将throw
语句放在一个if
块中,并且只更改条件,例如:
boolean shouldThrowException = false;
// ....
if ( shouldThrowException ) //place breakpoint here
{
throw new IOException();
}
When you hit the breakpoint, change the value of shouldThrowException
to true.
当您遇到断点时,将 的值更改shouldThrowException
为 true。
回答by mbaranauskas
回答by Andreas Wederbrand
I can't see how this can be done. I've tried two approaches (perhaps my ideas will lead to some other ideas
我看不出这是怎么做到的。我尝试了两种方法(也许我的想法会导致其他一些想法
1) I tried to use the debuggers "log evaluated expression" to throw new IOException()
but all I get is a message that IDEA couldn't evaluate the expression.
1)我尝试使用调试器“记录评估的表达式”,throw new IOException()
但我得到的只是一条消息,IDEA 无法评估表达式。
2) I also tried to set a break point and when it stopped I open up the "evaluate expression" dialog to throw a new exception but that didn't work either.
2)我还尝试设置一个断点,当它停止时,我打开“评估表达式”对话框以抛出一个新异常,但这也不起作用。
I don't think the debugger can throw exceptions.
@Binyamin's solution will work but you already mentioned that in your question. I can only add that in IDEA it's possible to uncheck the "suspend" checkbox and enter shouldThrowException = true
in the "log evaluated expression" box. This will cause the debugger to just change the value (and log it) but not stop which is great in code that have many concurrent threads.
我不认为调试器可以抛出异常。@Binyamin 的解决方案会起作用,但您已经在问题中提到了这一点。我只能在 IDEA 中添加,可以取消选中“挂起”复选框并shouldThrowException = true
在“日志评估表达式”框中输入。这将导致调试器仅更改值(并记录它)但不会停止,这在具有许多并发线程的代码中非常有用。
回答by maba
I don't know if you have tried this but you could perhaps create a static method that only throws IOException
and then call that method by issuing Evaluate Expression
.
我不知道你是否尝试过这个,但你也许可以创建一个静态方法,它只抛出IOException
然后通过发出Evaluate Expression
.
Simple example code:
简单示例代码:
package com.stackoverflow;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
doStuff();
}
private static void throwException() throws IOException {
throw new IOException();
}
private static void doStuff() {
System.out.println("doStuff");
}
}
Set a breakpoint on the System.out.println
line:
System.out.println
在行上设置断点:
Bring up the Evaluate Expression...
window and call the throwException
method (evaluate) and then you'll get a stack trace from within doStuff
:
调出Evaluate Expression...
窗口,并调用throwException
方法(评估),然后你会从内部得到一个堆栈跟踪doStuff
:
The exception will of course be in throwException
but you see the whole call stack as well.
例外当然会在,throwException
但您也会看到整个调用堆栈。
回答by maba
There is another way where you take advantage of the JVM HotSwapping.
还有另一种方法可以利用 JVM 热交换。
Let's assume that you are deploying code to some server. Then when you start the application make sure that you turn on remote debugging (which I think you have since you are debugging and are talking about deployment). If not then it will work evenly fine in the local debugger.
让我们假设您正在将代码部署到某个服务器。然后,当您启动应用程序时,请确保打开远程调试(我认为您在调试和谈论部署时就已经这样做了)。如果不是,那么它将在本地调试器中正常工作。
Now I have two classes, Main and Other.
现在我有两个类,Main 和 Other。
package com.stackoverflow;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
doStuff();
}
private static void doStuff() throws IOException {
System.out.println("doStuff");
Other.otherStuff();
}
public static void throwException() throws IOException {
throw new IOException();
}
}
package com.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Other {
public static void otherStuff() throws IOException {
File file = new File("Some_File.txt");
file.createNewFile();
}
}
The throwException()
could be placed anywhere as long as it is "globally" available, in some util class for example. Now it is just placed in my Main class for convenience.
在throwException()
可以任何地方,只要它是“全球”可被放置,例如在一些UTIL类。现在为了方便,它只是放在我的 Main 类中。
Now we can have a breakpoint set in our doStuff()
method and while being held there we can change the code in the otherStuff()
method so that it calls our static throwException()
method.
现在我们可以在我们的doStuff()
方法中设置一个断点,在断点的同时,我们可以更改otherStuff()
方法中的代码,以便它调用我们的静态throwException()
方法。
public static void otherStuff() throws IOException {
Main.throwException();
File file = new File("Some_File.txt");
file.createNewFile();
}
We have to call some method instead of invoking throw new IOException()
because otherwise we will have an error with Unreachable statement
.
我们必须调用一些方法而不是调用throw new IOException()
,否则我们将在Unreachable statement
.
Then we can press Ctrl+Shift+F9to recompile the Other class. It will now be HotSwapped (a dialog will ask if you really want to do this).
然后,我们可以按Ctrl+ Shift+F9重新编译其他类。它现在将是 HotSwapped(一个对话框会询问您是否真的想要这样做)。
Then press continue and the exception will be thrown.
然后按继续,将抛出异常。
The code can then be reverted back to normal state.
然后可以将代码恢复到正常状态。
The good thing about this is that the recompiled class will even be hot swapped "over the wire" to the remote machine.
这样做的好处是,重新编译的类甚至可以“通过网络”热交换到远程机器。
The important thing is that the code that you recompile must be in another class. The same class where you have your breakpoint won't be reloaded correctly.
重要的是您重新编译的代码必须在另一个类中。设置断点的同一个类将不会正确重新加载。
As a work around, I can modify the code to throw the exception and redeploy. But I'm wondering if there's a way to do this in the debugger without modifying source code.
作为一种变通方法,我可以修改代码以抛出异常并重新部署。但我想知道是否有一种方法可以在不修改源代码的情况下在调试器中执行此操作。
You will modify the code but only at the time when you want to, in the debugger. You can then revert back the small change and recompile to hot swap back the old code.
您将在调试器中修改代码,但仅在需要时进行。然后,您可以恢复小的更改并重新编译以热交换回旧代码。
I hope you get the idea (no pun intended).
我希望你能明白(不是双关语)。
I can add screenshots if you want to.
如果需要,我可以添加屏幕截图。