【问题标题】:Annotations: methods vs variables注释:方法和变量
【发布时间】:2010-05-19 20:24:42
【问题描述】:
我一直确信(不知道为什么)最好给变量添加注释,但是在浏览 Hibernate 文档http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-hibspec-collection 时,我注意到他们倾向于注释方法。所以我应该把我的注释放在方法之前,像这样:
@Entity
public class Flight implements Serializable {
private long id;
@Id @GeneratedValue
public long getId() { return id; }
public void setId(long id) { this.id = id; }
}
或者这样做更好:
@Entity
public class Flight implements Serializable {
@Id @GeneratedValue
private long id;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
}
或者也许没有区别?
【问题讨论】:
标签:
java
hibernate
jpa
jakarta-ee
【解决方案1】:
正如 Péter 指出的那样,您需要选择一种样式并坚持下去,因为 @Id 注释采用的样式将用于所有内容。
除此之外,这只是一个品味问题。这两个选项都有效,所以选择你喜欢的那个。有些人更喜欢 Hibernate 通过方法注入,以便他们可以在需要时巧妙地更改实现。我更喜欢通过字段注入,因为我发现必须通过 getter/setter 方法(7 行对 1 行)公开所有属性很麻烦,而在 99.9% 的情况下它们将作为简单变量工作(并且在任何情况下)如果/当我需要编写自定义设置器功能时,我可以切换注释样式。
两者之间没有性能或功能差异,因此请选择您喜欢的任何一个(或者更重要的是,选择您的团队/工具喜欢的那个)。
【解决方案2】:
使用@Id注解有区别:如果它在getter上,Hibernate会尝试通过它们的常规getter/setter来获取/设置所有类成员,而如果它在成员变量上,Hibernate将访问直接所有成员变量。
换句话说,您不能在同一个实体中混合样式。
【解决方案3】:
这取决于注释。
一般来说,如果实体具有与字段名称匹配的标准 getter/setter,那么差别不大。当有选择时,我倾向于注释字段,只是因为我发现用更难阅读的方法隐藏注释。
【解决方案4】:
选择放置它们的位置有时很方便,尤其是当字段未公开时。拥有私有 getter/setter 并不常见,因此能够在字段上添加注释很有用。
它有时也为使用外部/内部数据表示提供了一点灵活性。这是一个有点傻的例子,但我用过几次类似的技巧(here 和here):
@Column(...)
private String email;
public String getAlias() { ... split email and return the part before @ ... }
public void setAlias( String alias ) { ... change the part before the @ ... }
public String getHost() { ... split email and return the part after @ ... }
public void setHost(String host) { ... change the part after the @... }
一般来说,我倾向于将它们放在现场,我发现代码更具可读性。但这主要是品味问题。唯一要执行的规则是坚持!
【解决方案5】:
是的,我反对过多地注释内容。当您进行反射或类似的事情时,这很好,但我认为没有人想阅读注释只是因为有人想用它们替换 cmets。
【解决方案6】:
我强烈建议在变量上使用注解,而不是在方法上使用注解。这不是口味问题。如果要声明实现 Spring Security 的 UserDetails 的 USER 类,这是强制性的。
因此,以下代码将起作用,这是唯一的方法。
@Entity
class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany
private List<UserRole> roles;
//....Setters and Getters..........
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
如果您将所有注释放在函数 getter 上,而不映射 @OneToMany 或 @ManyToMany...它会起作用,但如果您需要使用这些关系,那么 Hibernate 会中断。我认为 Hibernate 已经在变量顶部使用注释,因此出于一致的原因它不喜欢函数顶部的注释。
因此,坚持框架的常规,您的代码不会在以后发生故障。