Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using mutable objects as a constant

Tags:

java

swing

Adding final to a primitive type variable makes it immutable.
Adding final to an object prevents you from changing its reference, but is still mutable.

I'm trying to use ImageIcon as a final constant, but at the same time, I don't want the image to be changeable. Is it okay to just use mutable objects as a constant, or are there any alternatives?

Example Constants:

public static final ImageIcon bit0 = new ImageIcon("bit0.png");
public static final ImageIcon bit1 = new ImageIcon("bit1.png");

Using the Constants:

JButton button = new JButton(ClassName.bit0);
JLabel label = new JLabel(ClassName.bit1);
like image 930
Edward Yang Avatar asked Feb 08 '23 03:02

Edward Yang


2 Answers

I'm trying to use ImageIcon as a final constant, but at the same time, I don't want the image to be changeable. Is it okay to just use mutable objects as a constant, or are there any alternatives?

Whether it's okay is up to you. :-) Exposing a public reference to a mutable object leaves it open to mutation, as you said, so probably not ideal.

In terms of alternatives: Since the JButton constructor you're using accepts Icon, and Icon is quite a simple interface with no mutation methods, you might want to create yourself an ImmutableIcon wrapper class and expose that.

E.g.:

class ImmutableIcon implements Icon {
    private Icon icon;

    public ImmutableIcon(Icon i) {
        this.icon = i;
    }

    public int getIconHeight() {
        return this.icon.getIconHeight();
    }

    public int getIconWidth() {
        return this.icon.getIconWidth();
    }

    public void paintIcon(Component c, Graphics g, int x, int y) {
        this.icon.paintIcon(c, g, x, y);
    }
}

then

public static final Icon bit0 = new ImmutableIcon(new ImageIcon("bit0.png"));
like image 185
T.J. Crowder Avatar answered Feb 13 '23 22:02

T.J. Crowder


Because ImageIcon is a reference type (instead of primitive), final here only means that the reference will always point to the same object. It says nothing about the state of that object.

If you're concerned about someone changing the object's state, you can wrap it in another object whose interface you have control over, or simply upcast to Icon if your other uses of the icon allow for that, e.g.

public static final Icon bit0 = new ImageIcon("bit0.png");

I'd also reconsider whether you need to expose the icon variable as a class constant. If you only ever make one instance of the containing class, then there are no savings from reuse.

As for whether or not mutable class constants are okay in general, I don't think there's any convention discouraging it, it just isn't always that useful. And since they're not garbage collected, you must be careful not to leak memory.

like image 24
johncip Avatar answered Feb 14 '23 00:02

johncip