Immutables: InitShim is always null so default value always will be returned

Created on 22 Jul 2016  路  6Comments  路  Source: immutables/immutables

Hi,

I debugged and found InitShim is always null and because of that, only default values will be returned.

@Value.Immutable(singleton = true, builder = false)
@Value.Style(visibility = Value.Style.ImplementationVisibility.PUBLIC)
public abstract class NextValidator {
    public static ImmutableNextValidator getInstance() {
        return ImmutableNextValidator.of();
    }

    @Value.Default
    @DrawableRes
    int drawableAlert() {
        return 0;
    }
}

Initializing NextValidator on Application:

NextValidator.getInstance().withDrawableAlert(R.drawable.ic_alert_circle);
NextValidator.getInstance().drawableAlert(); // always 0

Note: I'm using the latest version of Immutables.

Most helpful comment

Are you sure you need Immutable objects if you want to mutate static state? Maybe you can apply @Value.Modifiable to generate mutable companion object and pin an instance to a singleton (there's no autosingleton feature for modifiables) . Other that that it's not clear what you want to achieve.

All 6 comments

Hi. Isn't this an expected behavior? Objects are immutable so if you want to see value changed you need to assign copied instance.

NextValidator alertCircleValidator = NextValidator.getInstance().withDrawableAlert(R.drawable.ic_alert_circle);

alertCircleValidator.drawableAlert(); // always R.drawable.ic_alert_circle
NextValidator.getInstance().drawableAlert(); // always 0
assert alertCircleValidator != NextValidator.getInstance();
assert NextValidator.getInstance() == NextValidator.getInstance();

@elucash Thanks for your comment. Assigning to a variable is not the behavior i'm looking for. I want to be free from creating variables, so I decided to use singleton immutable class. In other words, I want to configure NextValidator once, then get the configured instance from invoking NextValidator.getInstance().

How about doing exactly that

@Value.Immutable(singleton = true, builder = false)
@Value.Style(visibility = Value.Style.ImplementationVisibility.PUBLIC)
public abstract class NextValidator {
    private static final NextValidator INSTANCE = ImmutableNextValidator.of().withDrawableAlert(R.drawable.ic_alert_circle);
    public static NextValidator getInstance() {
        return INSTANCE;
    }

    @Value.Default
    @DrawableRes
    int drawableAlert() {
        return 0;
    }
}

@elucash Thanks man but that's not what I'm looking for. I'm creating a new library and users must be able to customize NextValidator using with... methods, so I changed your edition a little bit:

@Value.Immutable(singleton = true, builder = false)
@Value.Style(visibility = Value.Style.ImplementationVisibility.PUBLIC)
public abstract class NextValidator {
    private static final ImmutableNextValidator INSTANCE = ImmutableNextValidator.of();

    public static ImmutableNextValidator getInstance() {
        return INSTANCE;
    }

    @Value.Default
    @DrawableRes
    int drawableAlert() {
        return 0;
    }
}

but the problem still exists.

Are you sure you need Immutable objects if you want to mutate static state? Maybe you can apply @Value.Modifiable to generate mutable companion object and pin an instance to a singleton (there's no autosingleton feature for modifiables) . Other that that it's not clear what you want to achieve.

@elucash Thanks man. Now users may initialize NextValidator and their configs are usable in my library.

@Value.Immutable(singleton = true, builder = false)
@Value.Modifiable
@Value.Style(visibility = Value.Style.ImplementationVisibility.PUBLIC)
public abstract class NextValidator {
    private static final ModifiableNextValidator INSTANCE = ModifiableNextValidator.create();

    public static ModifiableNextValidator getInstance() {
        return INSTANCE;
    }

    @Value.Default
    @DrawableRes
    int drawableAlert() {
        return 0;
    }
}
Was this page helpful?
0 / 5 - 0 ratings