Java中使用注释的常量正确性?

Java中使用注释的常量正确性?,java,annotations,constants,Java,Annotations,Constants,是否存在允许我将Java方法注释为@Const的现有库,以便编译器(我假定使用apt)在更新字段或调用字段上的非@Const方法时标记错误;并将参数注释为@Const,以便接受方法无法调用其任何非@Const方法或更新其任何字段 (基本上,尝试使用注释将常量正确性添加到Java中;上面的问题中没有涉及到一些明显的细节,例如向@const类型的参数赋值或从@const类型的参数赋值等。) 我发现了这一点:但它似乎只是想法的一部分 根据下面的澄清请求,以下是示例代码,以说明我的意思: class P

是否存在允许我将Java方法注释为@Const的现有库,以便编译器(我假定使用apt)在更新字段或调用字段上的非@Const方法时标记错误;并将参数注释为@Const,以便接受方法无法调用其任何非@Const方法或更新其任何字段

(基本上,尝试使用注释将常量正确性添加到Java中;上面的问题中没有涉及到一些明显的细节,例如向@const类型的参数赋值或从@const类型的参数赋值等。)

我发现了这一点:但它似乎只是想法的一部分

根据下面的澄清请求,以下是示例代码,以说明我的意思:

class Person {
  private String name;
  private String address;

  @Const public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  ... etc. for address
}
现在,如果我定义一个方法,例如:

void processPerson(@Const Person p)
像:
p.getName()
这样的行在
processPerson
中是可以的,因为
getName
被标记为@Const方法。但是从
processPerson
中调用
p.setName()
将被标记为错误

请注意,这与
final
非常不同:如果参数被定义为
final Person p
,则对
p
的任何赋值都是非法的,但修改
p
引用的内容仍然是完全有效的(使用
p.setName(…)
或者更直接地,使用
p.name=…

  • 应该就是你想要的

  • 就我个人而言,我想看看我是否可以使用它。它是一个很棒的小库(不依赖于hibernate,它很小),而且它对保持数据干净非常有用。请参阅

  • 谷歌的一个家伙最近也开始了,但这可能还不是生产质量

看看,它基本上有检查程序,可以通过可扩展类型注释系统[JSR-308]检测软件缺陷[JSR-305]

它有一个不变性检查器(实际上是2个),允许您使用不变性注释(如@Mutable、@Immutable和@Readonly)对代码进行注释。该工具区分了不变性实例和只读引用

我喜欢这个框架,主要用于空检查,但我正在尝试更多地使用不变性检查器和实习检查器

将参数注释为@Const,以便接受方法无法调用其任何非@Const方法或更新其任何字段

看起来像:

void addFriend(@ReadOnly Friend friend) { this.friends.add(friend); }
允许我将Java方法注释为@Const,以便编译器(假设使用apt)在更新字段或调用字段上的非@Const方法时标记错误;以及

问题中的示例如下所示:

public String getName(@ReadOnly Person this) {
  return name;
}
此处的
@ReadOnly
表示不应修改接收方(调用其方法的
实例)。尽管存在明显的额外参数,但仍会像往常一样调用该方法:

@ReadOnly Person person = new Person();
person.getName();


我附议@AlexR comment,这可以使用AspectJ完成,大致如下:

public aspect ConstAspect{
declare warning : withincode(* *(..,@Const (*),.. ) ) : "Calling Const Method..";
}

这对您的要求是不正确的,但我基本上想展示一种方法,在上面的情况下,任何一个参数都有一个@ const的方法被警告一个更好的连接点,所有关注点都可以加上一个错误。

<代码>代码> const 是C++的。java显然是故意丢弃它的。现在人们G在没有真正经验的情况下划船是个好主意

一旦你将一种方法标记为
const
,它就会像癌症一样扩散,很快你就会发现自己几乎什么都是
const
。最好使用
而不是const


完全没有用。它只在学术上有吸引力,在实际编程中对任何人都没有帮助。

你有没有尝试使用
final
关键字来实现这个目的?有什么问题吗?final方法是一个不能被重写的方法。这是不同的。final参数意味着该方法不能重新分配引用;但它仍然可以修改y参数所指的对象。这(a)不是我要找的,并且(b)完全没有用(至少在我看来)@M,这并不是完全没用,但如果你写了一些示例代码,也许会更容易理解你的意思?是的,你是对的。你真的可以在内部修改对象。我个人使用无框架解决方案来完成这类任务:如果是集合,我使用
collection.unmodifiablelist()包装它
等,如果它是我自己的类I,则可以实现不允许在类本身中修改的逻辑,或者更好地使用方面包装对象。方面可以使用方面框架(如AspectJ)之一实现或者我使用动态代理。我理解你希望有一个框架自动完成这个操作,祝你好运。这是非常非常有争议的。我在C++程序中使用了 const <代码>,我不记得它在扩展。把吸引子标记为const,并做访问操作符的const重载(如<代码>运算符[]/COD>)。确实有助于防止对对象的意外修改。我认为COST也很好(8年C++经验)。关于传播-方法上的异常规范如何?它确实像癌症一样传播,但Java开发人员设法忍受它。康斯特像癌症一样传播是件好事。康斯特纠正的内容越多,代码就越安全,不会被滥用。@EliasVasylenko我可以从编码的角度理解为什么它会让人恼火,因为它会导致sig性质看起来相当长。我认为方法参数应该始终被视为
const
,除非另外明确标记为
mutable
!我完全同意这一点。然而,在这个问题的背景下,我认为在想要选择一个合理的违约和想要我们假设的注释之间存在着一种紧张关系