寻找一种更简单的方法来用 Java 编写调试打印语句
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1239150/
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
Looking for an easier way to write debugging print statements in Java
提问by Lasoldo Solsifa
EDIT: I would love to read reactions to Steve Reed's AOP approach. Comments to his answer are encouraged!
编辑:我很想阅读对 Steve Reed 的 AOP 方法的反应。鼓励对他的回答发表评论!
I'm a novice, and at some point I realized it would be helpful to know the contents of a variable during program execution. So I started doing this:
我是新手,在某些时候我意识到在程序执行期间了解变量的内容会很有帮助。所以我开始这样做:
EDIT: fixed this. Used to be: var + ": " + var, which was totally wrong. Dumb typo.
编辑:修复了这个。曾经是:var + ":" + var,这是完全错误的。愚蠢的错别字。
System.err.println ( "var: " + var );
Later I learned that this was common practice. At least, where a debugger was unavailable or unwanted.
后来我才知道这是普遍做法。至少,在调试器不可用或不需要的地方。
I use a basic text editor, and typing the print statement every time I need to debug a variable is pretty tiresome, so I thought, why not something like this:
我使用一个基本的文本编辑器,每次我需要调试一个变量时都输入打印语句非常烦人,所以我想,为什么不这样:
void dbug ( Object obj )
{
String variableName = obj.somehowGetVariableName();
String variableContents = obj.toString();
System.out.println ( variableName +": " + variableContents );
}
But apparently getting the variable name is easier said than done.
但显然获得变量名说起来容易做起来难。
java-reflection-how-to-get-the-name-of-a-variable
java-reflection-how-to-the-name-of-a-variable
Am I stuck with:
我是否坚持:
System.err.println ( "var: " + var );
Or is there a popular shorthand version of this?
或者是否有流行的速记版本?
采纳答案by pjp
I wouldn't try and write any fancy methods around printing out debugging info. Just stick with either LOG.debug(...)
if you are using a logger or System.err.println(...)
otherwise.
我不会尝试编写任何关于打印调试信息的奇特方法。LOG.debug(...)
如果您使用记录器或System.err.println(...)
其他方式,请坚持使用。
You may wish to use String.format("var=%s val=%s", "VarName", val)
instead of the String concatenation.
您可能希望使用String.format("var=%s val=%s", "VarName", val)
代替字符串连接。
Make sure that you override the toString
method in each of your classes to provide meaningful debug info.
确保覆盖toString
每个类中的方法以提供有意义的调试信息。
At the end of the day it's often easier to fire up the debugger and take a look to see what's going on instead of having to trace through loads of logged debug lines.
在一天结束时,通常更容易启动调试器并查看发生了什么,而不必跟踪已记录的调试行的负载。
The only time when i'd use your kind of debug method would be if my application maintained all of the state inside a map which I could easily print out the key value pairs (e.g. the session map in a web application).
我使用您的调试方法的唯一时间是,如果我的应用程序在地图中维护所有状态,我可以轻松地打印出键值对(例如,Web 应用程序中的会话地图)。
回答by Tim
Have a look at Simple Logging Framework, it allows you to type:
看看Simple Logging Framework,它允许您输入:
class Example {
static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(Example.class);
void doSomething(Object obj1, Object obj2) {
LOG.debug("This is object 1: {}, and this is object 2: {}", obj1, obj2);
}
}
回答by Brian Agnew
Some thoughts:
一些想法:
I would implement
toString()
on objects of interest, and in that print out the members in a friendlyfashion (e.g. convert timestamps to a readable format etc.). I usually choose a format like:Object[member1=,member2=...]
Otherwise printing the object alone will give you the classname plus the identity hash code, and (as you've discovered) that's not hugely useful!
Commons has a facility to do this automatically. But here's a simple
toString()
tutorialwhich I think is more appropriate.There are logging frameworks that you may be interested in in the future. e.g. check out Log4j. At the moment, however, I wouldn't worry about that.
回答by Juri
Personally I don't suggest to use sysout statements anywhere. You should always use a debugger (using some IDE). I cannot imagine where this wouldn't be wanted.
我个人不建议在任何地方使用 sysout 语句。您应该始终使用调试器(使用某些 IDE)。我无法想象这不会被需要。
Otherwise I'm suggesting logging frameworks like log4j, but again, this already gets more complicated where I would again then switch to a real IDE with debugger.
否则,我建议使用 log4j 之类的日志记录框架,但同样,这已经变得更加复杂,我将再次切换到带有调试器的真实 IDE。
回答by dfa
I think that System.err.formatis what you want:
我认为System.err.format是你想要的:
System.err.format("var: %s\n", var);
is a shorthand for:
是以下的简写:
System.err.println(String.format("var: %s", var));
回答by Steve Reed
You can get access to the variable names with AOP and compile-time weaving. The nice thing about this is that if you don't do the weaving, you don't add the debug logging code and your runtime code is leaner and quicker as a result.
您可以使用 AOP 和编译时编织来访问变量名称。这样做的好处是,如果您不进行编织,就不会添加调试日志记录代码,因此您的运行时代码会更精简、更快。
Here's an example of using AspectJ to throw an exception when a field is set to null. Note the usage of "joinPoint.getSignature()
" to get access to the code metadata.
下面是一个使用 AspectJ 在字段设置为 null 时抛出异常的示例。请注意使用“ joinPoint.getSignature()
”来访问代码元数据。
@Aspect
public class NotNullValidator {
@Pointcut(value = "set(@com.acme.NotNull * *.*) && args(valueBeingSet)")
private void setOfNonNullField(final Object valueBeingSet) { }
@Before(value = "setOfNonNullField(valueBeingSet)")
public void validate(final JoinPoint joinPoint, final Object valueBeingSet) {
if (valueBeingSet == null) {
throw new NullPointerException("Cannot set " + joinPoint.getSignature().getName() + " to null.");
}
}
}
See JoinPoint Javadocto see what else you can get (line numbers, source and target objects, etc).
请参阅JoinPoint Javadoc以了解您还可以获得什么(行号、源和目标对象等)。
回答by Carl Manaster
It's a stretch, but...
这是一个延伸,但是...
You're getting advice to use an IDE instead of a simple text editor. I'd go along with that, 100%.
您得到的建议是使用 IDE 而不是简单的文本编辑器。我会同意,100%。
You're getting advice to use a logging framework or a debugger instead of println() calls. Well, sure, but...
你得到了使用日志框架或调试器而不是 println() 调用的建议。嗯,当然,但是...
Better yet is unit tests. Don't ask what it is - tell it what you expect. Then, the integrated unit-testing framework (junit, typically) will verify that you're getting what you expect. The more I use unit tests, the less I need debugging and the less I need println's. And when something changes, the testing framework tells me - I don't need to manually re-evaluate every test's output, just watch the bar.
更好的是单元测试。不要问它是什么——告诉它你的期望。然后,集成的单元测试框架(通常是junit)将验证您是否获得了预期的结果。我使用单元测试越多,我需要调试的就越少,我需要 println 的就越少。当某些事情发生变化时,测试框架会告诉我 - 我不需要手动重新评估每个测试的输出,只需观察条形图即可。
Unit tests are better than debugging, better than logging. They're not a 100% replacement for debugging and logging, but start using them and you'll find much less need for those tedious activities.
单元测试比调试好,比日志记录好。它们不是调试和日志记录的 100% 替代品,但开始使用它们,您会发现对那些乏味的活动的需求要少得多。
回答by Naveed Kamran
I would recommend you to properly configure and use Apache Log4J. System.out or System.err lines cause a lot of delay in execution of program. (You can confirm this by adding some time info that how much time your program takes without System.out etc and how much without these lines.)
我建议您正确配置和使用 Apache Log4J。System.out 或 System.err 行会导致程序执行大量延迟。(您可以通过添加一些时间信息来确认这一点,即您的程序在没有 System.out 等的情况下需要多少时间以及没有这些行需要多少时间。)
Logging APIs use separate threads to log your logging info in log files, thats why they are more useful in realistic applications. Also logging APIs like Log4J give a lot of control over how to configure and format your logs. For example look here a few logs generated from Log4J:
日志 API 使用单独的线程将您的日志信息记录在日志文件中,这就是它们在实际应用程序中更有用的原因。此外,Log4J 等日志 API 可以对如何配置和格式化日志进行大量控制。例如,看看这里从 Log4J 生成的一些日志:
2012-01-05 15:16:41,730 [main] 16 DEBUG dmfssecbuild.IOUtil -
2012-01-05 15:16:41,730 [main] 16 DEBUG dmfssecbuild.IOUtil - Application Configs Loaded
2012-01-05 15:16:41,730 [main] 16 DEBUG dmfssecbuild.Constants - Running Application between dates.
2012-01-05 15:16:41,730 [main] 16 DEBUG dmfssecbuild.Constants - Sat Jan 01 00:00:00 GMT+05:00 2011 From Date
2012-01-05 15:16:41,730 [main] 16 DEBUG dmfssecbuild.Constants - Mon Dec 31 00:00:00 GMT+05:00 2012 To Date
回答by Cedric Reichenbach
Have you tried DoodleDebug? It's an Eclipse plugin and meant to be as easy as System.out.println()
but much more powerful.
你试过 DoodleDebug 吗?它是一个 Eclipse 插件,旨在尽可能简单System.out.println()
但功能更强大。
It can be found here: http://scg.unibe.ch/wiki/projects/DoodleDebug
回答by arviman
If you use IntelliJ IDEA, you can use the "Live template" shortcut for printing to System.out such as soutp (and then a TAB)
to debug the method parameters, soutv
to trace the name of a variable along with it's value, etc.
如果您使用 IntelliJ IDEA,您可以使用“实时模板”快捷方式打印到 System.out,例如soutp (and then a TAB)
调试方法参数、soutv
跟踪变量名称及其值等。
To read the list of shortcuts\modify it, go to File->Settings->Live Templates->Output
要阅读快捷方式列表\修改它,请转到文件->设置->实时模板->输出