Java 这些 PMD 规则的原因是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1615419/
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
What is the reason for these PMD rules?
提问by Thomas Owens
DataflowAnomalyAnalysis: Found 'DD'-anomaly for variable 'variable' (lines 'n1'-'n2').
DataflowAnomalyAnalysis: Found 'DU'-anomaly for variable 'variable' (lines 'n1'-'n2').
DataflowAnomalyAnalysis:发现变量“variable”的“DD”异常(行“n1”-“n2”)。
DataflowAnomalyAnalysis:发现变量“variable”的“DU”异常(行“n1”-“n2”)。
DD and DU sound familiar...I want to say in things like testing and analysis relating to weakest pre and post conditions, but I don't remember the specifics.
DD 和 DU 听起来很耳熟……我想在与最弱的前后条件相关的测试和分析方面说,但我不记得具体细节。
NullAssignment: Assigning an Object to null is a code smell. Consider refactoring.
NullAssignment:将对象分配给 null 是一种代码异味。考虑重构。
Wouldn't setting an object to null
assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
null
如果对象是本地对象(不在方法之外使用),是否不会设置对象来协助垃圾收集?或者这是一个神话?
MethodArgumentCouldBeFinal: Parameter 'param' is not assigned and could be declared final
LocalVariableCouldBeFinal: Local variable 'variable' could be declared final
MethodArgumentCouldBeFinal:参数“param”未分配,可以声明为最终
LocalVariableCouldBeFinal:局部变量“变量”可以声明为最终的
Are there any advantages to using final
parameters and variables?
使用final
参数和变量有什么好处吗?
LooseCoupling: Avoid using implementation types like 'LinkedList'; use the interface instead
LooseCoupling:避免使用像“LinkedList”这样的实现类型;改用接口
If I know that I specifically need a LinkedList
, why would I not use one to make my intentions explicitly clear to future developers? It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
如果我知道我特别需要一个LinkedList
,为什么我不使用一个来向未来的开发人员明确表达我的意图?返回有意义的类路径最高的类是一回事,但为什么我不声明我的变量是最严格的呢?
AvoidSynchronizedAtMethodLevel: Use block level rather than method level synchronization
避免SynchronizedAtMethodLevel:使用块级而不是方法级同步
What advantages does block-level synchronization have over method-level synchronization?
块级同步比方法级同步有什么优势?
AvoidUsingShortType: Do not use the short type
避免UsingShortType:不要使用short类型
My first languages were C and C++, but in the Java world, why should I not use the type that best describes my data?
我的第一门语言是 C 和 C++,但在 Java 世界中,为什么我不应该使用最能描述我的数据的类型?
采纳答案by erickson
DD and DU anomalies (if I remember correctly—I use FindBugs and the messages are a little different) refer to assigning a value to a local variable that is never read, usually because it is reassigned another value before ever being read. A typical case would be initializing some variable with
null
when it is declared. Don't declare the variable until it's needed.Assigning
null
to a local variable in order to "assist" the garbage collector is a myth. PMD is letting you know this is just counter-productive clutter.Specifying final on a local variable shouldbe very useful to an optimizer, but I don't have any concrete examples of current JITs taking advantage of this hint. I have found it useful in reasoning about the correctness of my own code.
Specifying interfaces in terms of… well, interfacesis a great design practice. You can easily change implementations of the collection without impacting the caller at all. That's what interfaces are all about.
I can't think of many cases where a caller would requirea
LinkedList
, since it doesn't expose any API that isn't declared by some interface. If the client relies on that API, it's available through the correct interface.Block level synchronization allows the critical section to be smaller, which allows as much work to be done concurrently as possible. Perhaps more importantly, it allows the use of a lock object that is privately controlled by the enclosing object. This way, you can guarantee that no deadlock can occur. Using the instance itself as a lock, anyone can synchronize on it incorrectly, causing deadlock.
Operands of type
short
are promoted toint
in any operations. This rule is letting you know that this promotion is occurring, and you might as well use anint
. However, using theshort
type can save memory, so if it is an instance member, I'd probably ignore that rule.
DD 和 DU 异常(如果我没记错的话——我使用 FindBugs 并且消息有点不同)是指将一个值分配给一个从未被读取的局部变量,通常是因为它在被读取之前被重新分配了另一个值。一个典型的情况
null
是在声明某个变量时对其进行初始化。在需要之前不要声明变量。分配
null
给局部变量以“协助”垃圾收集器是一个神话。PMD 让您知道这只是适得其反的混乱。在一个局部变量指定最后应该是给优化是非常有用的,但我没有考虑这个提示的优势,目前即时编译器的任何具体的例子。我发现它有助于推理我自己的代码的正确性。
根据……来指定接口,接口是一个很好的设计实践。您可以轻松更改集合的实现,而根本不会影响调用者。这就是接口的全部意义所在。
我想不出很多情况下调用者需要a
LinkedList
,因为它不会公开任何未由某些接口声明的 API。如果客户端依赖该 API,则可以通过正确的接口使用它。块级同步允许临界区更小,这允许尽可能多的工作同时完成。也许更重要的是,它允许使用由封闭对象私有控制的锁对象。这样,您可以保证不会发生死锁。使用实例本身作为锁,任何人都可以错误地对其进行同步,从而导致死锁。
在任何操作
short
中都会提升类型的操作数int
。此规则让您知道此促销活动正在发生,您不妨使用int
. 但是,使用short
类型可以节省内存,因此如果它是实例成员,我可能会忽略该规则。
回答by OscarRyz
DataflowAnomalyAnalysis: Found 'DD'-anomaly for variable 'variable' (lines 'n1'-'n2').
DataflowAnomalyAnalysis: Found 'DU'-anomaly for variable 'variable' (lines 'n1'-'n2').
DataflowAnomalyAnalysis:发现变量“variable”的“DD”异常(行“n1”-“n2”)。
DataflowAnomalyAnalysis:发现变量“variable”的“DU”异常(行“n1”-“n2”)。
No idea.
不知道。
NullAssignment: Assigning an Object to null is a code smell. Consider refactoring.
Wouldn't setting an object to
null
assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
NullAssignment:将对象分配给 null 是一种代码异味。考虑重构。
null
如果对象是本地对象(不在方法之外使用),是否不会设置对象来协助垃圾收集?或者这是一个神话?
Objects in local methods are marked to be garbage collected once the method returns. Setting them to null won't do any difference.
一旦方法返回,本地方法中的对象就会被标记为垃圾回收。将它们设置为 null 不会有任何区别。
Since it would make less experience developers what is that null assignment all about it may be considered a code smell.
因为它会减少开发人员的经验,所以关于它的空分配可能被认为是一种代码气味。
MethodArgumentCouldBeFinal: Parameter 'param' is not assigned and could be declared final
LocalVariableCouldBeFinal: Local variable 'variable' could be declared final
Are there any advantages to using
final
parameters and variables?
MethodArgumentCouldBeFinal:参数“param”未分配,可以声明为最终
LocalVariableCouldBeFinal:局部变量“变量”可以声明为最终的
使用
final
参数和变量有什么好处吗?
It make clearer that the value won't change during the lifecycle of the object.
它更清楚地表明该值在对象的生命周期内不会改变。
Also, if by any chance someone try to assign a value, the compiler will prevent this coding error at compile type.
此外,如果有人尝试分配值,编译器将在编译类型中防止此编码错误。
consider this:
考虑一下:
public void businessRule( SomeImportantArgument important ) {
if( important.xyz() ){
doXyz();
}
// some fuzzy logic here
important = new NotSoImportant();
// add for/if's/while etc
if( important.abc() ){ // <-- bug
burnTheHouse();
}
}
Suppose that you're assigned to solve some mysterious bug that from time to time burns the house.
假设你被分配去解决一些不时烧毁房子的神秘错误。
You know what wast the parameter used, what you don't understand is WHYthe burnTHeHouse
method is invoked if the conditions are not met ( according to your findings )
您知道使用的参数有什么用处,您不明白的是为什么在burnTHeHouse
不满足条件的情况下调用该方法(根据您的发现)
It make take you a while to findout that at some point in the middle, somonechange the reference, and that you are using otherobject.
您需要一段时间才能发现在中间的某个点,有人更改了引用,并且您正在使用其他对象。
Using final
help to prevent this kind of things.
使用final
帮助来防止这种事情。
LooseCoupling: Avoid using implementation types like 'LinkedList'; use the interface instead
If I know that I specifically need a
LinkedList
, why would I not use one to make my intentions explicitly clear to future developers? It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
LooseCoupling:避免使用像“LinkedList”这样的实现类型;改用接口
如果我知道我特别需要一个
LinkedList
,为什么我不使用一个来向未来的开发人员明确表达我的意图?返回有意义的类路径最高的类是一回事,但为什么我不声明我的变量是最严格的呢?
There is no difference, in this case. I would think that since you are not using LinkedList
specific functionality the suggestion is fair.
在这种情况下,没有区别。我认为由于您没有使用LinkedList
特定功能,因此该建议是公平的。
Today, LinkedList could make sense, but by using an interface you help your self ( or others ) to change it easily when it wont.
今天,LinkedList 可能有意义,但是通过使用一个界面,您可以帮助您自己(或其他人)在它不会更改时轻松更改它。
For small, personal projects this may not make sense at all, but since you're using an analyzer already, I guess you care about the code quality already.
对于小型的个人项目,这可能根本没有意义,但由于您已经在使用分析器,我猜您已经关心代码质量了。
Also, helps less experienced developer to create good habits. [ I'm not saying you're one but the analyzer does not know you ;) ]
此外,帮助经验不足的开发人员养成良好的习惯。[我不是说你是一个,但分析器不认识你;)]
AvoidSynchronizedAtMethodLevel: Use block level rather than method level synchronization
What advantages does block-level synchronization have over method-level synchronization?
避免SynchronizedAtMethodLevel:使用块级而不是方法级同步
块级同步比方法级同步有什么优势?
The smaller the synchronized section the better. That's it.
同步部分越小越好。就是这样。
Also, if you synchronize at the method level you'll block the whole object. When you synchronize at block level, you just synchronize that specific section, in some situations that's what you need.
此外,如果您在方法级别同步,您将阻塞整个对象。当您在块级别同步时,您只需同步该特定部分,在某些情况下这正是您所需要的。
AvoidUsingShortType: Do not use the short type
My first languages were C and C++, but in the Java world, why should I not use the type that best describes my data?
避免UsingShortType:不要使用short类型
我的第一门语言是 C 和 C++,但在 Java 世界中,为什么我不应该使用最能描述我的数据的类型?
I've never heard of this, and I agree with you :) I've never use short though.
我从来没有听说过这个,我同意你的看法 :) 不过我从来没有使用过 short 。
My guess is that by not using it, you'll been helping your self to upgrade to int
seamlessly.
我的猜测是,如果不使用它,您将帮助自己int
无缝升级 。
Code smells are more oriented to code quality than performance optimizations. So the advice are given for less experienced programmers and to avoid pitfalls, than to improve program speed.
代码味道更侧重于代码质量而不是性能优化。所以这些建议是为经验不足的程序员提供的,避免陷阱,而不是提高程序速度。
This way, you could save a lot of time and frustrations when trying to change the code to fit a better design.
这样,您可以在尝试更改代码以适应更好的设计时节省大量时间和麻烦。
If it the advise doesn't make sense, just ignore them, remember, you are the developer at charge, and the tool is just that a tool. If something goes wrong, you can't blame the tool, right?
如果建议没有意义,请忽略它们,记住,您是负责的开发人员,而该工具只是一个工具。如果出现问题,您不能责怪该工具,对吗?
回答by DefyGravity
AvoidUsingShortType: Do not use the short type
避免UsingShortType:不要使用short类型
List item
short is 16 bit, 2's compliment in java
- a short mathmatical operaion with anything in the Integer family outside of another short will require a runtime sign extension conversion to the larger size. operating against a floating point requires sign extension and a non-trivial conversion to IEEE-754.
- can't find proof, but with a 32 bit or 64 bit register, you're no longer saving on 'processor instructions' at the bytecode level. You're parking a compact car in a a semi-trailer's parking spot as far as the processor register is concerned.
- If your are optimizing your project at the byte code level, wow. just wow. ;P
- I agree on the design side of ignoring this pmd warning, just weigh accurately describing your object with a 'short' versus the incurred performance conversions.
- in my opinion, the incurred performance hits are miniscule on most machines. ignore the error.
项目清单
short 是 16 位,Java 中的 2 的恭维
- 在另一个 short 之外的 Integer 系列中的任何内容的简短数学运算将需要运行时符号扩展转换为更大的大小。针对浮点操作需要符号扩展和到 IEEE-754 的非平凡转换。
- 找不到证据,但是使用 32 位或 64 位寄存器,您不再在字节码级别节省“处理器指令”。就处理器寄存器而言,您将一辆小型汽车停在半挂车的停车位。
- 如果您正在字节码级别优化您的项目,哇。哇哦。;P
- 我同意忽略此 pmd 警告的设计方面,只需权衡使用“短”准确描述您的对象与产生的性能转换。
- 在我看来,在大多数机器上产生的性能损失是微乎其微的。忽略错误。
回答by Michael Borgwardt
Wouldn't setting an object to null assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
如果对象是本地对象(不在方法之外使用),是否不会将对象设置为 null 辅助垃圾收集?或者这是一个神话?
The only thing it does is make it possible for the object to be GCd before the method's end, which is rarely ever necessary.
它所做的唯一一件事就是让对象在方法结束之前被 GCd 成为可能,这很少需要。
Are there any advantages to using final parameters and variables?
使用最终参数和变量有什么好处吗?
It makes the code somewhat clearer since you don't have to worry about the value being changed somwhere when you analyze the code. More often then not you don't need or want to change a variable's value once it's set anyway.
它使代码更加清晰,因为您在分析代码时不必担心值会在某处更改。通常情况下,一旦设置了变量,您就不需要或不想更改它的值。
If I know that I specifically need a LinkedList, why would I not use one to make my intentions explicitly clear to future developers?
如果我知道我特别需要 LinkedList,为什么我不使用 LinkedList 向未来的开发人员明确表达我的意图?
Can you think of any reason why you would specifically need a LinkedList?
你能想出你特别需要 LinkedList 的任何原因吗?
It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
返回有意义的类路径最高的类是一回事,但为什么我不声明我的变量是最严格的呢?
I don't care much about local variables or fields, but if you declare a method parameter of type LinkedList
, I will hunt you down and hurt you, because it makes it impossible for me to use things like Arrays.asList()
and Collections.emptyList()
.
我不太关心局部变量或字段,但是如果你声明一个 type 的方法参数LinkedList
,我会追捕你并伤害你,因为它使我无法使用像Arrays.asList()
and 之类的东西Collections.emptyList()
。
What advantages does block-level synchronization have over method-level synchronization?
块级同步比方法级同步有什么优势?
The biggest one is that it enables you to use a dedicated monitor object so that only those critical sections are mutually exclusive that need to be, rather than everything using the same monitor.
最大的一个是它使您能够使用专用的监视器对象,以便只有那些关键部分是相互排斥的,而不是使用同一个监视器的所有部分。
in the Java world, why should I not use the type that best describes my data?
在 Java 世界中,为什么我不应该使用最能描述我的数据的类型?
Because types smaller than int are automtically promoted to int for all calculations and you have to cast down to assign anything to them. This leads to cluttered code and quite a lot of confustion (especially when autoboxing is involved).
因为对于所有计算,小于 int 的类型都会自动提升为 int,并且您必须向下转型才能为它们分配任何内容。这会导致代码混乱和相当多的混乱(尤其是在涉及自动装箱时)。
回答by user2427
What advantages does block-level synchronization have over method-level synchronization? Synchronize a method is like do a
synchronize(getClass())
block, and blocks all the class.
块级同步比方法级同步有什么优势?同步一个方法就像做一个
synchronize(getClass())
块,并块所有的类。
Maybe you don't want that
也许你不想那样
回答by Thorbj?rn Ravn Andersen
Just a note on the final
question.
只是对这个final
问题的说明。
Putting "final" on a variable results in it only be assignable once. This does not necessarily mean that it is easier to write, but it most certainly means that it is easier to readfor a future maintainer.
将“final”放在变量上会导致它只能赋值一次。这并不一定意味着它更容易编写,但它肯定意味着对于未来的维护者来说更容易阅读。
Please consider these points:
请考虑以下几点:
- any variable with a
final
can be immediately classified in "will not change value while watching". - by implication it means that if all variables which will not change are marked with final, then the variables NOT marked with final actually WILL change.
- 任何带有 a 的变量
final
都可以立即归类为“在观看时不会改变值”。 - 这意味着如果所有不会改变的变量都标记为 final,那么没有标记为 final 的变量实际上会改变。
This means that you can see already when reading through the definition part which variables to look out for, as they may change value during the code, and the maintainer can spend his/her efforts better as the code is more readable.
这意味着您在阅读定义部分时已经可以看到要注意哪些变量,因为它们可能会在代码期间改变值,并且由于代码更具可读性,维护者可以更好地花费他/她的努力。