Mutable boolean field in Java
Asked Answered
G

9

45

I need a mutable boolean field in Java (I will return this field via get* method later and it should be possible to modify this field).

Boolean doesn't work because there are no set* methods in the Boolean class (I would say that Boolean is immutable, you can only change the reference, but you can't change the object itself).

I guess I can use Boolean array of size 1. But probably there are more elegant solutions?

Why doesn't Java have such a simple thing?

Gluttonize answered 6/9, 2009 at 11:46 Comment(2)
Boolean values are normally tested using isXXX methods instead of getXXXHenriettahenriette
@Henriettahenriette isXXX is only for those primitive booleans. We should stick to getXXX for those Booleans.Maidenhead
L
66

Immutable classes are easier to work with. They'll never change and there will be no problems with concurrent code. (Basically, there are fewer possibilities to break them.)

If you would like to return a reference to your Boolean value, you can use java.util.concurrent.atomic.AtomicBoolean if you're working with multiple threads or plain old org.apache.commons.lang.mutable.MutableBoolean.

Liponis answered 6/9, 2009 at 11:54 Comment(5)
I did write "mutable" in my java.lang.String comment object and could not change it again. :-)Liponis
this one is intersting. probably i should realy use AtomicBoolean... thanksGluttonize
hm.. this is what I've read in javadoc: "An AtomicBoolean is used in applications such as atomically updated flags, and cannot be used as a replacement for a Boolean.". Why?Gluttonize
It has an other API. Some features are missing like parsing and Comparable is not implemented. The performance characterics of AtomicBoolean will be different, too.Liponis
MutableBoolean - very useful. Can be made final for use in lambdas when you don't need to overhead of locking associated with AtomicBoolean. Thank you!Dunnock
D
29

Maybe write yourself a wrapper class

class BooleanHolder {
    public boolean value;
}

Or make a generic holder class (which means you will have to use class Boolean instead of primitive boolean):

class Holder<T> {
    public T value;
}

You then return the wrapper class instead of the value itself, which allows the value inside the wrapper to be modified.

Dallas answered 6/9, 2009 at 11:52 Comment(5)
this will work, but array of size 1 is a little simpler, imho :)Gluttonize
You make an array of BooleanHolders if you need more than 1Polyhydric
Doesn't allow you to use it as boolean.Sacksen
@TomášZato That wasn't the question. I provided two possible ways of using a mutable boolean field/parameter. Why the downvote?Dallas
@AdamBatkin Sorry I came here from google and I didn't pay enough attention to the original question. Strangely, my vote is locked though.Sacksen
C
24

If you are using Java 5 or higher then use AtomicBoolean

Corotto answered 26/1, 2010 at 18:44 Comment(3)
@monzonj: The java.util.concurrent classes do not use synchronized, they use the much better optmized locking constructs. AtomicBoolean will have a totally insignificant performance overhead when used as a contained for a boolean. if you can demonstrate otherwise, please show us.Divagate
@monzonj: It doesn't have a significant performance overhead at all in any case. Also there is a lot to be gained from using the right tool for the right job. Regardless of what you think of some micro-performance hit that you can't measure, this highly optimized class was created for a reason, I doubt you can do better.Corotto
@monzonj - your assertion that "atomic assignments can only be done through synchronization" is mis-informed at best, there is the concept of lock free synchronization and if you actually look at the source for AtomicBoolean you will see that there is no usage of the synchronized keyword anywhere! You are spreading misinformation with your uninformed comment at best.Corotto
A
9

You can use a boolean array

final boolean[] values = { false };
values[0] = true;
Audriaaudrie answered 28/3, 2013 at 7:0 Comment(0)
A
5

Why not use the boolean primitive ?

e.g.

private boolean myFlag = false;

public void setMyFlag(boolean flag) {
   myFlag = flag;
}

Note your getter method can return a Boolean if required, due to the magic of autoboxing. This allows easy interchangeability between using primitives and their object equivalents (e.g. boolean vs. Boolean, or int vs. Integer).

So to address your edited responses re. the methods you have available,

public Object getAttribute(String attributeName)

can be implemented by returning an autoboxed boolean,.

Another answered 6/9, 2009 at 11:50 Comment(4)
i don't want to add special method to set something... everything should be implemented via Object returned from getAttribute. This is because i don't want to change very top-hierarchy class interface. all I need is a mutable boolean object... i do think that java.util.concurrent.atomic.AtomicBoolean probably the right choiceGluttonize
Whilst I understand what you're doing, I'd say that I'm not sure this is a good design. I'd expect the containing object to look after manipulating fields, rather than handing them off to 3rd party code to change. i.e. it's the responsibility of the containing object to look after its fields and maintain consistent state etc. Just a heads up (you may be working under constraints that I'm not aware of, however)Another
i agree in most cases we should not use such practics. even "findbugs" reports "Array return type" as a "poor design" because object can be changed by third-parties. But this is how a lot of code already written and I just need to add few more things :) Moreover from the name of my field it will be clear that it supposed to be changed by third-parties, so I think it should not be a big problem :)Gluttonize
So long as you're aware of the issues. Sounds like you are :-)Another
Z
5

What about just using the boolean primitive?

private boolean value;

public void setValue(boolean value) {
    this.value = value;
}

public boolean getValue() {
    return value;
}
Zetland answered 6/9, 2009 at 11:52 Comment(3)
this will work but you have to write two methods for each field. but i don't want to change existent interface. the only method I have is: public Object getAttrbiute(String attributeName)Gluttonize
Adding the ability to set things is, in common sense terms, changing the interface. So it is best to have the actual written interface change to represent and track that change.Helicograph
@Helicograph +1 That's a great way to think about the problem.Inhalation
B
3

The answer I liked most was from Adam to write your own wrapper class... OK

/* Boolean to be passed as reference parameter */
public class Bool {

     private boolean value;

     public Bool() {
         this.value = false;
     }

     public boolean is() {
         return this.value;
     }

     public void setTrue() {
         this.value = true;
     }

     public void setFalse() {
         this.value = false;
     }
 }
Bremsstrahlung answered 8/8, 2016 at 8:5 Comment(0)
C
0

If you are using Android, you can use the android.util.Mutable* objects which wrap various primitive values. For example, quoting from the SDK source:

public final class MutableBoolean {
  public boolean value;

  public MutableBoolean(boolean value) {
      this.value = value;
  }
}
Castorena answered 29/1, 2016 at 18:43 Comment(0)
D
-1

Are you really saying that you want callers to be able to modify the object's boolean value by manipulating what gets returned? So that the object and caller would share a reference to it?

Just so I understand, given:

class OddClass {
   private Boolean strangeFlag;
   public Object getAttrbiute(String attributeName) { 
      if (attributeName.equals("strangeflag")) return (Object)strangeFlag; 
      ...
   }
}

And then caller does:

   Boolean manipulableFlag = (Boolean) myOddClass.getAttrbiute ("strangeflag");

And then later, if caller changes the value of manipulableFlag, you want that change to happen in the OddClass instance, just as though caller had instead used a setAttrbiute method.

Is that what you're asking?

In that case, you'd need a holder class, as suggested by Adam.

Devitt answered 6/9, 2009 at 14:37 Comment(1)
that's right, you understanding is correct. holder class is heavy workaround. at least i can use one-element array, but probably java.util.concurrent.atomic.AtomicBoolean is the best choiceGluttonize

© 2022 - 2024 — McMap. All rights reserved.