我现在正在使用看起来像这样的代码
public String getName(User user) {
user.setSth(...);
return user.getName();
}
我认为更改作为参数传递的对象是不好的做法。有没有一种工具可以检测到那种代码?我查看了findbugs,pmd和checkstyle,但找不到任何检查。
P.S。抱歉的坏例子。
答案 0 :(得分:2)
你找不到任何东西,因为从工具的角度来看,“getName”和“setSth”只是方法调用。人类说“这是一个吸气剂”和“这是一个制定者”,但工具却没有。实际上,getName()不是getter,因为getter不接受参数。
因此,该工具无法看到任何异常,因为方法始终会更改对象。
如果要强制执行此规则,请查看扩展findbugs和PMD。两者都允许您定义其他约束。您正在寻找的可能是:
然后打印警告。这不应该花太长时间。运行此命令,您将看到有多少“误报”(关于方法实际上可以正常的警告)。这将有助于您确定是否值得进一步追求。另外,您将有一个新项目添加到您的简历中:)
答案 1 :(得分:2)
你可以使User
不可变(声明它final
,声明所有属性final
并远程设置。我知道这在任何地方都不可用,但在很多地方都是好的,将它传递给其他函数你没有任何问题。)
如果您必须“更改”某些内容,则可以在该示例中实现newId
之类的功能:
public final class User {
private final String name;
private final int id;
User(String name, int id) {
this.name = name;
this.id = id;
}
public User newId(int newId) {
return new User(this.name, newId);
}
//getters here;
}
内置的String
,Integer
,...类也可以这样做。
答案 2 :(得分:2)
我认为你已经走在正确的轨道上:检测这类代码的最佳工具几乎肯定是Findbugs。但是,您可能需要为此模式编写自己的检测器。 Here is an example如何编写探测器,尽管它并不是您正在寻找的探测器。
警告:我真的不同意副作用的吸气剂总是坏的风格。但是,如果你真的想找到那种东西,我会推荐Findbugs。
答案 3 :(得分:1)
您可以创建一个名为UserView的界面,仅包含“getters”,让用户实现它并使用新的UserView界面作为参数类型。
interface UserView{
public String getName();
...
class User implements UserView...
public String getName(UserView user) {
user.setSth(...); // Will not compile
return user.getName();
}
答案 4 :(得分:1)
实际上,这是通过const
限定符在C ++中很容易实现的。您可以将参数定义为const
,对于该参数,您只能调用定义为const
的方法 - 通常是getters。
在Java中,这是不存在的,坦率地说,我并不介意。如上所述,有源代码分析器可以检查这种行为,以及元编程方法也可以这样做。
就个人而言,我相信如果方法命名正确,没有将对象传递给它的问题,以便修改它。
答案 5 :(得分:0)
有些工具可以比编译器通常更高级别地“推理”代码。例如,声明性元编程是一门学科,它允许编写程序来检查另一个程序是否符合某种设计,或者相反地,挖掘代码气味和反模式。
一些链接:
http://www.cs.bris.ac.uk/Publications/pub_master.jsp?id=1000273
其余
http://www.google.com/search?num=100&hl=en&q=Declarative+Metaprogramming
答案 6 :(得分:0)
你在C ++中寻找类似“const”的东西,它会强制使参数值与传入的引用一样不可变。不可变对象保证,如果你可以使用它们。
你认为这是“坏事”,因为这样的副作用会让用户感到惊讶。这是有效的,但只有当它是不受欢迎的惊喜时它才有害。