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);
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"));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With