Java 反对注释的论点

Java 反对注释的论点,java,coding-style,annotations,Java,Coding Style,Annotations,我的团队正在迁移到Spring3.0,有些人希望开始将所有内容迁移到注释中。当我看到一个类有这样的方法时,我的内心有一种非常不好的感觉(代码味道?)(只是一个例子——不是所有真正的注释) 我只是落后于时代,还是这对其他人来说都是一个可怕的想法?现在,一切都是按照惯例或通过注释进行的,而不是使用诸如继承和多态性之类的OO概念。我只是不喜欢。必须重新编译所有代码来更改IMO配置的内容似乎是错误的。但一切(尤其是春天)似乎都是这样。我是应该“克服它”,还是应该回过头来尽量让我们的代码不需要注释?事实上

我的团队正在迁移到Spring3.0,有些人希望开始将所有内容迁移到注释中。当我看到一个类有这样的方法时,我的内心有一种非常不好的感觉(代码味道?)(只是一个例子——不是所有真正的注释)


我只是落后于时代,还是这对其他人来说都是一个可怕的想法?现在,一切都是按照惯例或通过注释进行的,而不是使用诸如继承和多态性之类的OO概念。我只是不喜欢。必须重新编译所有代码来更改IMO配置的内容似乎是错误的。但一切(尤其是春天)似乎都是这样。我是应该“克服它”,还是应该回过头来尽量让我们的代码不需要注释?

事实上,我认为你内心对注释的反感更多地与这种将配置与代码混合在一起的注释有关

就我个人而言,我的感觉和您一样,我更愿意将配置(如事务定义、路径元素、控制器应映射到的URL等)留在代码库本身之外,并保留在外部SpringXML上下文文件中


虽然我认为正确的方法取决于意见和您喜欢哪种方法,但我预计一半的社区会同意注释方法,另一半会同意外部配置方法。

检查这些类似问题的答案


基本上可以归结为:两者兼用。它们都有用例。不要将注释用于那些不需要重新编译就可以配置的东西(尤其是那些用户不需要重新编译就可以配置的东西)

我最初也对注释持怀疑态度,但看到它们在使用,它们可能是一件好事。它们也可能被过度使用

关于注释,要记住的主要一点是它们是静态的。它们不能在运行时更改。任何其他配置方法(xml、代码中的自我描述等)都不会受到这种影响。我在这里看到过一些人对Spring有一些问题,比如在注入测试配置时有一个测试环境,并且不得不使用XML来完成测试

XML不是多态的、继承的或其他任何东西,因此从这个意义上讲,它不是倒退

注释的优点是,它可以为您的配置提供更多的静态检查,并且可以避免XML配置中的大量冗长和协调困难(基本上保持干燥)

与XML一样,注释也可能被过度使用。主要的一点是平衡每一种方法的需要和优点。注释是一种可以利用的工具,它可以减少代码的冗长和枯燥

编辑:关于注释替换接口或抽象类的评论,我认为这在框架边界是合理的。在一个计划由数百个(如果不是数千个)项目使用的框架中,拥有一个接口或基类确实可以压缩一些东西(特别是基类,尽管如果可以使用注释,没有理由不能使用常规接口)

以JUnit4为例。之前,您必须扩展具有安装和拆卸方法的基类。就我而言,这些基类是在接口上还是在基类中并不重要。现在,我有一个完全独立的项目,它有自己的继承层次结构,它们都必须遵守此方法。首先,它们不能有自己的继承层次结构冲突的方法名称(在测试框架中不是什么大问题,但你明白我的意思)。其次,你一直都有调用super的链条,因为所有方法都必须耦合

现在使用JUnit4,您可以在层次结构中的不同类中拥有不同的@Before方法,并且它们可以彼此独立。没有注释,没有同样枯燥的方法可以实现这一点

从JUnit开发人员的角度来看,这是一场灾难。最好有一个定义好的类型,可以调用setUp和teardown。但是框架的存在不是为了方便框架开发人员,而是为了方便框架用户

如果您的代码不需要关心类型(也就是说,在您的示例中,没有任何东西会真正使用控制器类型),那么所有这些都适用。然后您甚至可以说实现框架的接口比添加注释更容易泄漏


但是,如果您要编写代码来读取自己项目中的注释,请远离它。

我个人认为注释接管了太多内容,并且超出了其原始和超级有用的用途(例如,指示重写方法之类的小事情)我觉得JAva机制不够健壮,无法处理每个方法之前的注释集群。 例如,我最近一直在与JUnit注释作斗争,因为它们以我不喜欢的方式限制我

话虽如此,以我的经验,基于XML的配置也不是很好,所以引用South Park的话,您可以在巨大的灌洗器和t*rd三明治之间进行选择


我认为您必须做出的主要决定是,您是否更习惯于对spring配置进行非本地化(即,维护两个文件而不是一个文件),以及您是否使用从注释中获益的工具或IDE插件。另一个重要的问题是,将使用或维护您的代码的开发人员是否真正理解注释。

可能您对代码中到处都是的冗余注释有问题。冗余注释可以被替换,您的注释至少是干的

从Spring博客:

@Service
@Scope("request")
@Transactional(rollbackFor=Exception.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyService {
}

@MyService
public class RewardsService {
…
}
因为Java在进化
@Service
@Scope("request")
@Transactional(rollbackFor=Exception.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyService {
}

@MyService
public class RewardsService {
…
}
@Entity
class Person
{
    @Column
    private String firstname;
    public String getFirstname() { return firstname; }
    public void setFirstname(String value) { firstname = value; }

    @Column
    private String surname;
    public String getSurname() { return surname; }
    public void setSurname(String value) { surname = value; }

}
class PersonEntity extends Entity<Person> {
    @Override
    public Class<Person> getEntityClass() { return Person.class;}

    @Override
    public Collection<PersistentProperty> getPersistentProperties() {
         LinkedList<PersistentProperty> result = new LinkedList<>();
         result.add(new PersistentProperty<Person>(Person#getFirstname, Person#setFirstname);
         result.add(new PersistentProperty<Person>(Person#getSurname, Person#setSurname);
         return result;
    }
}