11

我对 Java 5 注释有点陌生,我很好奇是否有可能:

此注释将为您生成一个简单的 getter 和 setter。

@attribute
private String var = "";

注释表明变量不能为空,@NotNull因此您不必每次都编写该样板代码。

/*
 * @param s @NotNull
 */
public void setString(String s){
    ...
}

这些中的任何一个都可以吗?如果可以的话,它们似乎是我写注释的第一件事。因为当我阅读文档时我看不到太多关于这些的内容,所以我假设这并不是注释的真正含义。这里的任何方向将不胜感激。

4

7 回答 7

15

注释处理发生在抽象语法树上。这是解析器创建和编译器操作的结构。

当前的规范(链接来)说注释处理器不能改变抽象语法树。这样做的后果之一是不适合进行代码生成。

如果您喜欢这种功能,请查看XDoclet。这应该为您提供我认为您正在寻找的代码生成预处理。

对于您的@NonNull示例,JSR-305是一用于增强软件缺陷检测的注释,包括@NonNull@CheckForNull以及许多其他注释。

编辑Project Lombok正好解决了 getter 和 setter 生成的问题。

于 2008-12-08T10:31:38.727 回答
14

Getters/Setters:是的,这是可能的。Lombok 项目( http://projectlombok.org/index.html ) 定义了用于生成 getter/setter 等的 注释。

所以例如

@lombok.Data;
public class Person {
   private final String name;
   private int age;
}

将生成getName(没有设置器,因为变量是最终的)和getAge/ setAge。它还将生成equalshashCodetoString初始化所需字段的构造函数(name在本例中)。添加@AllArgsConstructor将生成一个初始化两个字段的构造函数。使用@Value而不是@Data将使对象不可变。

还有其他注释和参数可以让您控制访问权限(您的 getter 是否应该受到保护或公开)、名称(getName()name()?)等。还有更多。例如,我非常喜欢构建器扩展方法的注释。

Lombok 非常易于使用:

  • 只需下载 jar 并使用注释,自动生成的 getter/setter 可以在您的代码中使用,而无需实际拼写出来。
  • 注释仅在编译期间而不是在运行时使用,因此您不要将 lombok 与您的 jar 一起分发。
  • 大多数 IDE 都支持这一点,因此您可以在代码完成、导航等中看到 getter/setter。在 Netbeans 中,这是开箱即用的。在 IntelliJ IDEA 中使用Lombok 插件

NotNull:findbugs 和 IDEA IDE 支持,也许还有其他支持

于 2010-02-02T18:06:01.947 回答
4

有没有办法在 Java 中使用注释来替换访问器?

简而言之,不,Java 5/6 编译器不支持此功能,第三方很难以与编译器无关的方式添加此类支持。

为了更好地处理注释,我将从JUnit开始。如果您为版本 3(预注释)和 4(基于注释)编写代码,您很快就会了解框架如何将基于命名模式的合同替换为基于注释的合同。

举一个更生动的例子,比较 EJB 2 和 EJB 3。

于 2008-12-08T01:21:03.457 回答
4

您所指的@attribute 也不能与注释一起使用,因为它们现在在Java 中(正如jamesh 指出的那样)。

您可能正在寻找的是Java 中尚不存在的“属性”。但它现在是一个非常热门的话题,我们可能会在 Java 7 或 Java 8 中得到它们(因为我仍然停留在 1.4.2 上,它对我没有帮助,但它可能会帮助你)。

在Java Posse 第 219 集中,有一个有趣的讨论暗示使用注释实现属性。

于 2008-12-08T10:48:13.890 回答
2

有一个名为 OVal 的项目,我认为它可以满足您的需求。 http://oval.sourceforge.net/

如果我记得之前需要 AspectJ 的话,但是没有 AspectJ 的简单检查工作。看看这个。

还有 Hibernate Validator,也检查一下:P

于 2008-12-08T12:42:49.713 回答
2

这是可能的,只是不是在你声明它们的地方。

查看http://code.google.com/p/javadude/wiki/Annotations

我有一个类注释为

package sample;
import com.javadude.annotation.Bean;
import com.javadude.annotation.Property;
import com.javadude.annotation.PropertyKind; 

@Bean(properties={
    @Property(name="name"),
    @Property(name="phone", bound=true),
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
})
public class Person extends PersonGen {}

它会为你生成 PersonGen 类,包含 getter/setter 等

处理器也做得更多。请注意,我正在开发一个新版本,它与当前版本相比有一点 API 损坏

于 2009-03-25T14:29:16.117 回答
1

尽管它们有时很有用,但如果您严重缺少属性,那么您可能在整个 OO 设计方面有点不稳定。

OO 设计的理念是,方法是“动作”,您要求对象为您做某事——不仅仅是设置或获取值——这不是一个对象,而是一个结构。

如果您认为缺少属性是一个严重的问题,我强烈建议您尝试编码一段时间,而不要使用 setter 和抵制 getter。

一开始可能很难,但我敢打赌,到最后你会更牢固地掌握 OO 设计原则。

(注意:在极少数情况下,您必须在构建对象后执行“setter”类型操作——最常见的情况是您必须创建两个相互引用的对象。在这种情况下,我建议您使用类似构建器模式的东西setter 必须被调用一次并且被保护不被调用两次)

于 2010-02-02T18:29:54.553 回答