You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring项目打包Jar时出现Lombok重写兼容错误

问题描述

我在基于Spring的Java IntelliJ项目中打包Jar文件时遇到编译错误:Lombok的@Getter注解自动生成的get_status()方法与父类Model中的get_status()方法冲突,返回类型Subscription.Status(枚举类型)和父类的java.lang.String不兼容,且我并未主动重写该方法。

相关代码片段:

@Getter @Setter
private Status _status;

完整错误信息:

java: get_status() in <directive>.models.users.sub_users.subscriptions.Subscription cannot override get_status() in <directive>.models.Model
return type <directive>.models.users.sub_users.subscriptions.Subscription.Status is not compatible with java.lang.String

该问题仅出现在这个枚举属性上,其他枚举属性使用Lombok注解均正常。以下是Subscription类的完整代码:

/**
 * Defines the kind of subscription a user is having.
 * Only Artists and Bands can have a paying subscription.
 */
@ToString
public class Subscription extends Model {

    /**
     * The User that uses this Subscription.
     */
    @Getter
    private User _user;

    /**
     * An enum that contains different kinds of types, that this Subscription can be.
     * Will also determine the price.
     */
    @Getter
    private Type _type;

    /**
     * An enum that determines what kind of status, the situation of the Subscription is in.
     */
    @Getter @Setter
    private Status _status;

    /**
     * How much the User should pay per month.
     */
    private int _price;

    /**
     * An object class that specifies the offer if any, that this Subscription has.
     */
    @Getter @Setter
    private SubscriptionOffer _offer;

    /**
     * The id in the database of the card, that is connected to this subscription.
     * Is only the id and not the object for security reasons.
     */
    @Getter
    private Long _cardId;

    public Subscription(User user, Type type, Status status, SubscriptionOffer offer, Long cardId, LocalDateTime timestamp) {
        super(user.get_primaryId(), cardId, user.get_username()+"-Subscription: " + user.get_primaryId(), timestamp);
        _type = defineType(type);
        _status = status;
        _offer = offer;
        _cardId = cardId;
    }

    public Subscription(long id, Type type, Status status, SubscriptionOffer offer, Long cardId) {
        super(id, cardId, "Unkown_user-Subscription: " + id);
        _type = defineType(type);
        _status = status;
        _offer = offer;
        _cardId = cardId;
        _timestamp = null;
    }

    public Subscription(User user, Type type, Status status, SubscriptionOffer offer, Long cardId) {
        super(user.get_title() + "-Subscription");
        _user = user;
        _type = defineType(type);
        _status = status;
        _offer = offer;
        _cardId = cardId;
    }

    /**
     * Set the id of the card, that is connection to this Subscription,
     * but will only do so, if the id is not already set.
     * @param id The id value that will be set as the connection between this subscription and the card of that id.
     * @return The id of the card, that is connected to this Subscription.
     */
    public Long set_cardId(long id) {
        if (_cardId==null)
            _cardId = id;

        return _cardId;
    }

    /**
     * This is only meant to be used in User class after assemble.
     * Will only set the User, if the User is null.
     * @param user The User that will be set for this Subscription.
     * @return The User of this Subscription.
     */
    public User set_user(User user) {
        if (user == null)
            _user = user;

        return _user;
    }

    /**
     * Uses the defineType() method to set the type and also the price from the new type value.
     * @param type An enum of a SubscriptionType, that is wished to be set.
     * @return The SubscriptionType of this Subscription.
     */
    public Type set_type(Type type) { return defineType(type); }

    /**
     * Sets the type of this Subscription and also determines the price for that type of Subscription.
     * @param type An enum of a type of Subscription, that is wished to be set.
     * @return This Subscription's type as the enum.
     */
    private Type defineType(Type type) {
        _type = type;

        if (_user.getClass() != Artist.class && _user.getClass() != Band.class) {
            switch (_type) {
                case PREMIUM_BAND -> {
                    if (_user.getClass() == Band.class) _price = 100;
                }
                case PREMIUM_ARTIST -> {
                    if (_user.getClass() == Artist.class && ((Artist) _user).get_bands().size() == 0) _price = 60;
                }
                default -> _price = 0;
            }
        }
        return _type;
    }

    /**
     * Checks if there is a free trial offer or the User is either a Band or Artist,
     * since they are the only paying Users.
     * Also calculates the Offer effect with the price.
     *
     * @return The price per month of the User as a double, since it is multiplied with the Offer effect.
     */
    public double get_price() {
        if (_user != null &&
                ((_user.getClass() == Band.class || _user.getClass() == Artist.class) &&
                (_offer.get_type() != SubscriptionOffer.Type.FREE_TRIAL && !isOfferExpired())))
            return isOfferExpired() ? _price : _price * _offer.get_effect();
        else return 0;
    }

    /**
     * Determines whether the date that this offer's date has been reached or not.
     * Counts from LocalDateTime.now.
     * @return True if the moment now is after the date that the offer of this Subscription will expire, otherwise false.
     */
    public boolean isOfferExpired() { return LocalDateTime.now().isAfter(_offer.get_expires()); }

    /**
     * An enum that can be of different types, determining the type of Subscription.
     */
    public enum Type {
        FREEMIUM,
        PREMIUM_BAND,
        PREMIUM_ARTIST
    }

    /**
     * An enum that defines Status that a Subscription is currently in.
     */
    public enum Status {
        ACCEPTED,
        BLOCKED,
        DISACTIVATED,
        CLOSED
    }
}
解决方案

1. 修改属性名称规避冲突

直接修改子类中属性的名称,避免和父类属性(或其生成的getter)重名。比如把_status改为_subscriptionStatus,Lombok会生成get_subscriptionStatus()方法,自然不会和父类的get_status()冲突:

@Getter @Setter
private Status _subscriptionStatus;

2. 自定义Getter方法名称

通过Lombok注解指定自定义的getter方法名,绕过默认的命名规则:

@Getter(getterName = "getSubscriptionStatus")
@Setter(setterName = "setSubscriptionStatus")
private Status _status;

注:部分Lombok版本可能使用@Accessor注解来指定方法名,语法为@Getter(onMethod_ = {@Accessor("getSubscriptionStatus")}),需根据实际使用的Lombok版本调整。

3. 调整父类方法(若可行)

如果父类Model的代码可修改,可考虑修改其get_status()方法的名称或返回类型,从根源解决冲突。但如果父类是第三方依赖或不可修改,优先选择前两种方案。

内容的提问来源于stack exchange,提问作者Laustrup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:35:35