String.format
在Java中使用和字符串连接之间是否存在明显的差异?
我倾向于使用,String.format
但偶尔会滑倒并使用concat.我想知道一个人是否比另一个好.
我看到它的方式,String.format
给你"格式化"字符串更多的权力; 和连接意味着您不必担心意外地添加额外的%s或丢失一个%s.
String.format
也更短.
哪一个更具可读性取决于你的头部如何工作.
在阅读" 你的/你的圈复杂度有什么限制? "之后,我意识到我的很多同事对我们项目的新QA政策非常恼火:每个功能不再有10个圈复杂度.
含义:不超过10'if','else','try','catch'和其他代码工作流程分支语句.对.正如我在' 你测试私人方法吗?',这样的政策有很多好的副作用.
但是:在我们(200人 - 7年)项目开始时,我们很高兴地记录(不,我们不能轻易地将其委托给某种' 面向方面编程 '的日志方法).
myLogger.info("A String");
myLogger.fine("A more complicated String");
...
Run Code Online (Sandbox Code Playgroud)
当我们的系统的第一个版本上线时,我们遇到了巨大的内存问题,不是因为日志记录(在某一点被关闭),而是因为日志参数(字符串),总是被计算,然后传递给'info()'或'fine()'函数,只是发现日志记录级别为"OFF",并且没有记录日志!
所以QA回来并敦促我们的程序员进行条件记录.总是.
if(myLogger.isLoggable(Level.INFO) { myLogger.info("A String");
if(myLogger.isLoggable(Level.FINE) { myLogger.fine("A more complicated String");
...
Run Code Online (Sandbox Code Playgroud)
但是现在,由于每个功能限制的"无法移动"10个圈复杂度级别,他们认为他们在其功能中放入的各种日志被视为负担,因为每个"if(isLoggable())"是计为+1圈复杂度!
因此,如果一个函数有8'if','else'等等,在一个紧密耦合的不易共享的算法中,以及3个关键的日志操作......它们违反了限制,即使条件日志可能不是真的该功能的复杂性的一部分......
你会如何解决这种情况?
我在项目中看到过几个有趣的编码演变(由于这个'冲突'),但我只是想先了解你的想法.
谢谢你的所有答案.
我必须坚持认为问题不是"格式化"相关,而是"参数评估"相关(评估可能非常昂贵,只是在调用一个什么都不做的方法之前)
所以当写一个上面的"A String"时,我实际上意味着机能缺失(),与机能缺失()返回一个字符串,并且是一个复杂的方法收集的调用和计算所有类型的日志数据被记录器...与否(因此该问题,并显示义务,以使用条件记录,因此人为增加'圈复杂度'的实际问题......)
我现在得到你们中某些人提出的" 可变函数"点(谢谢John).
注意:java6中的快速测试表明我的varargs函数在被调用之前会对其参数进行求值,所以它不能用于函数调用,而是用于'Log Retriever object'(或'function wrapper'),其中toString( )只有在需要时才会被调用.得到它了.
我现在已经发表了关于这个主题的经验.
我会留在那里直到下周二投票,然后我会选择你的一个答案.
再次,谢谢你的所有建议:)
language-agnostic logging coding-style cyclomatic-complexity
有没有必要做一个明确的if(log.isDebugEnabled()){...}检查?
我的意思是我看到一些帖子提到log.debug("something")在进行日志记录之前进行隐式调用以查看是否已启用调试模式日志记录.我错过了什么,或者在使用之前是否有中间步骤?
谢谢!
log.debug("ResultSet rs is retrieved from OracleTypes");
Run Code Online (Sandbox Code Playgroud)
VS
if(log.isDebugEnabled()){
log.debug("ResultSet rs is retrieved from OracleTypes");
}
Run Code Online (Sandbox Code Playgroud)
编辑:写了这篇文章:http: //java.sg/whether-to-do-a-isdebugenabled-checking-before-printing-out-your-log-statement/
我正在使用SonarLint向我显示以下行中的问题.
LOGGER.debug("Comparing objects: " + object1 + " and " + object2);
Run Code Online (Sandbox Code Playgroud)
附注:包含此行的方法可能会经常调用.
这个问题的描述是
"先决条件"和记录参数不应该要求评估(鱿鱼:S2629)
将需要进一步评估的消息参数传递到Guava com.google.common.base.Preconditions检查可能会导致性能下降.这是因为无论是否需要它们,必须在实际调用方法之前解析每个参数.
类似地,将连接的字符串传递给日志记录方法也会导致不必要的性能损失,因为每次调用该方法时都会执行连接,无论日志级别是否足够低以显示消息.
相反,您应该构造代码以将静态或预先计算的值传递到Preconditions条件检查和记录调用.
具体来说,应该使用内置字符串格式而不是字符串连接,如果消息是方法调用的结果,那么应该跳过前提条件,并且应该有条件地抛出相关的异常.
不合规的代码示例
Run Code Online (Sandbox Code Playgroud)logger.log(Level.DEBUG, "Something went wrong: " + message); // Noncompliant; string concatenation performed even when log level too high to show DEBUG messages LOG.error("Unable to open file " + csvPath, e); // Noncompliant Preconditions.checkState(a > 0, "Arg must be positive, but got " + a); // Noncompliant. String concatenation performed even when a > 0 Preconditions.checkState(condition, formatMessage()); //Noncompliant. …
我见过人们使用log4j的方式如下:
if(logger.isDebugEnabled())
{
logger.debug(" message ");
}
Run Code Online (Sandbox Code Playgroud)
但是,我检查了logger.debug
API 的文档,发现它debug
在记录消息之前检查是否已启用.在那种情况下,写出额外的if是什么意思?
只是写不一样
logger.debug(" message ");
Run Code Online (Sandbox Code Playgroud)
?
日志记录是否会降低应用程 以及如何限制在日志文件中打印显示标签日志?
例如.我的日志文件有以下日志
[2012-06-20 15:52:06,290] org.displaytag.tags.TableTag isFirstIteration 684 - [data] first iteration=true (row number=1)
[2012-06-20 15:52:06,290] org.displaytag.tags.TableTag isFirstIteration 684 - [data] first iteration=true (row number=1)
[2012-06-20 15:52:06,290] org.displaytag.tags.TableTag isFirstIteration 684 - [data] first iteration=true (row number=1)
[2012-06-20 15:52:06,290] org.displaytag.tags.TableTag isFirstIteration 684 - [data] first iteration=true (row number=1)
Run Code Online (Sandbox Code Playgroud)
为什么以上是在日志文件中?
log.properties文件
# Log4j configuration file.
log4j.rootCategory=DEBUG, A1
# Available levels are DEBUG, INFO, WARN, ERROR, FATAL
#
# A1 is a ConsoleAppender
#
log4j.appender.A1 = org.apache.log4j.RollingFileAppender
log4j.appender.A1.File = C:/LogInfo/logfile.log
log4j.appender.A1.MaxFileSize = 100MB …
Run Code Online (Sandbox Code Playgroud) 我经常听到人们说,这是在日志记录时避免String Concatenation
和使用的最佳实践之一{}
。
我正在查看Log4j
代码,以了解他们如何处理此问题,并认为他们正在做类似的事情。
这是format()
方法的代码片段,其中包含模式和参数,并返回要记录的消息。
/**
* Formats arguments using SLF4J-like formatter.
* @param pattern pattern, may be malformed.
* @param arguments arguments.
* @return Message string
*/
private static String format(final String pattern,
final Object[] arguments) {
if (pattern != null) {
String retval = "";
int count = 0;
int prev = 0;
int pos = pattern.indexOf("{");
while(pos >= 0) {
if (pos == 0 || pattern.charAt(pos-1) != '\\') {
retval …
Run Code Online (Sandbox Code Playgroud) 我正在进行代码审查,我想你想到一小段代码:
if(logger.isDebugEnabled())
{
logger.debug("debug log");
}
Run Code Online (Sandbox Code Playgroud)
进行测试有真正的原因/好处if(logger.isDebugEnabled())
吗?
为什么不在logger.debug("debug log");
没有测试的情况下写?
java ×7
log4j ×5
logging ×5
string ×2
coding-style ×1
if-statement ×1
performance ×1
sonarlint ×1