【问题标题】:Can I annotate a member inherited from a superclass?我可以注释从超类继承的成员吗?
【发布时间】:2013-06-23 13:04:24
【问题描述】:

如果我有这样的课程:

class Person {
  private String name;
  ...constructor, getters, setters, equals, hashcode, tostring...
}

我是否可以子类化并将注释应用到子类中的名称字段,例如应用持久性注释,而无需重新实现类的其余部分?

@Entity
class Employee extends Person {
    @Column(...)
    private String name;
}

【问题讨论】:

  • 您可以覆盖 getter/setter 并将 @Column 放在那里。

标签: java inheritance annotations


【解决方案1】:

不,你不能。

您提议的是字段 shadowing - 您不能覆盖字段。

子类中的字段name与超类中的字段name没有任何关系,只是同名“name”,从而区分超类中的字段,一必须在子类中将其称为super.name

这样做通常被认为是“错误”(或无论如何都是潜在错误),最佳做法是不要隐藏字段,因为很容易在不知情的情况下引用错误的字段。

【讨论】:

  • 我认为你没有抓住重点。问题在于注释超类中定义的成员,而不是隐藏它们。
  • @david 问题是关于希望通过“覆盖”字段来为超类字段添加注释,这是您无法做到的; OP 已遮蔽超类字段,这对超类字段没有影响。您不能从子类中注释超类的成员。
【解决方案2】:

这不会起作用,因为超类中的字段不会受到影响,但你可以试试这个

@Entity
class Employee extends Person {
  @Column(name="xxx")
  @Override
  public void setName(String name) {
     super.setName(name);
  }
  ...

【讨论】:

  • 对于被覆盖的 (@Override) getter 方法也有效,而且我想说更清楚。
【解决方案3】:

不 - 您将获得两个不同的字段。 Employee 中带注释的名称字段将隐藏 Person 类中的名称字段。 Person.name 不会被注释。

【讨论】:

    【解决方案4】:

    迟到的答案,但我认为覆盖 getter 方法是一种可靠的方法。

    这可以是所有具有 id 字段的表的超类。如果您将此对象序列化为 JSON,则 id 将始终出现。

    @MappedSuperclass
    class ModelEntity {
    
        @Id
        @Column(
            name      = "id",
            updatable = false,
            nullable  = false
        )
        @GeneratedValue(strategy=GenerationType.AUTO)
        public Long id
    }
    

    但是假设您有以下对象(表)PersonOccupation 其中PersonOccupation 具有一对多关系。

    @Entity
    @Table(name = "occupation")
    Occupation extends ModelEntity {
    
        @Column
        String company
    
        @Column 
        String position
    }
    
    @Entity
    @Table(name = "person")
    Person extends ModelEntity {
    
        @Column
        String name
    
        @OneToMany
        Occupation occupation
    }
    

    假设 id 存在于所有扩展 ModelEntity 的类中,如果你要序列化 ​​Person 对象,你会得到类似的东西:

    {
        "id" : 1,
        "name" : "Jordan",
    
        "occupation" : {
            "id" : 1,
            "company" : "WalMart",
            "position" : "Engineer"
        }
    
    }
    

    如果您不希望 id 出现在 Occupation 对象中,但确实希望它出现在 Person 对象中,则可以在 Occupation 类级别实现 getId() 方法,并应用所需的注释:

    @Transient
    public Long getId() {
    
        return id;   
    }
    

    现在您的 JSON 将如下所示:即使它们在实际数据库中都有一个 id 列:

    {
        "id" : 1,
        "name" : "Jordan",
    
        "occupation" : {
            "company" : "WalMart",
            "position" : "Engineer"
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 2011-12-18
      • 2013-10-09
      • 1970-01-01
      相关资源
      最近更新 更多