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

时间:2008-12-08 00:23:22

标签: java annotations metaprogramming

我对Java 5注释有点新,如果其中任何一种都可能,我很好奇:

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

@attribute
private String var = "";

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

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

其中任何一个都有效吗?如果可以的话,它们似乎是我会写注释的第一件事。因为当我阅读文档时,我没有看到太多这些,我假设它不是真正的注释。这里的任何方向都将受到赞赏。

7 个答案:

答案 0 :(得分:15)

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

当前规范(链接到来)说注释处理器不能改变抽象语法树。其中一个后果是它不适合进行代码生成。

如果您想要这种功能,请查看XDoclet。这应该给你代码生成预处理我认为你正在寻找。

对于@NonNull示例,JSR-305set of annotations,用于增强软件缺陷检测功能,包括@NonNull@CheckForNull以及其他许多内容。

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

答案 1 :(得分:13)

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

所以例如

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

将生成名称的getter(因为它是final而不是setter)和getter / setter for age。它还会生成equalshashCodetoString和construtor初始化必填字段(名称)。添加@AllArgsConstructor将生成初始化两个字段的构造函数。

还有其他注释和参数可让您控制访问权限(如果您的getter受到保护或公开),名称(getName或名称?)等等。还有更多。例如,我真的很喜欢扩展方法。

龙目岛非常容易使用。只需下载jar并使用注释,然后可以在代码中使用getter / setter而不会实际拼写出来。此外,像Netbeans这样的IDE支持这一点,因此您可以在代码完成,导航等中看到getter / setter。注释仅在编译期间使用,而不是在运行时使用,因此您不会使用jar来分发lombok。

NotNull:这是由findbugs和IdeaJ IDE支持的,也许是其他人

答案 2 :(得分:4)

  

有没有办法在中使用注释?   Java取代访问者?

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

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

有关更具戏剧性的示例,请将EJB 2与EJB 3进行比较。

答案 3 :(得分:4)

你指的@attribute太不能使用注释,因为它们现在是Java(正如jamesh指出的那样)。

你可能正在寻找的是“properties”,这在Java中还不存在。但是现在是一个非常热门的话题,我们可能会用Java 7或者Java 8来获取它们(因为我仍然坚持1.4.2它不会帮助我,但它可能对你有帮助。)

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

答案 4 :(得分:2)

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

如果我记得正确的事情需要AspectJ,不管是没有AspectJ的简单检查工作。看看吧。

还有Hibernate Validator,请查看:P

答案 5 :(得分: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破坏的新版本

答案 6 :(得分:1)

虽然它们有时很有用,但如果你严重缺少属性,那么你对整个OO设计的东西可能有点不稳定。

OO设计的想法是方法是“动作”,你要求对象为你做一些事情 - 不只是设置或获取值 - 这不是一个对象,它是一个结构。

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

一开始可能很难,但我最后打赌你会更加坚定地掌握OO的设计原则。

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