Can a method call of an object's object be executed simultaneously with an instance of the object?

I am trying to use the java BitSet class as a field for a custom class. And I want the class to use the default BitSet with all the bits set.

 import java.util.BitSet; public class MyClass { private BitSet mask; public MyClass() { this(new BitSet(4)); // want to set all bits first // something like // this( new BitSet(4).set(0,3) ); } public MyClass(BitSet mask) { this.mask = mask; } } 

By default, the BitSet constructor disables all bits. Therefore, before sending it as an anonymous object, I would like to call the set(int, int) method to set all the bits. I know that I could just initialize the mask field with a new BitSet and then call the set(int, int) method.

However, in general, I wonder if it is possible to access the instance method while creating the object?

+5
source share
3 answers

Why not write a separate constructor that allows BitSet initialization? Using Java 8, it might look something like this:

 public class MyClass { private BitSet mask; public MyClass() { this(new BitSet(4),(m)->m.set(0,3)); } public MyClass(BitSet mask,Consumer<BitSet> initializer) { initializer.accept(mask); this.mask = mask; } } 

You can even make it more general by introducing a static method with parameters like:

 public static <T> T initialize(T t,Consumer<T> initializer) { initializer.accept(t); return t; } 

In this case, the previous MyClass would look like this:

 public class MyClass { private BitSet mask; public MyClass() { this(initialize(new BitSet(4),(m)->m.set(0,3))); } public MyClass(BitSet mask) { this.mask = mask; } } 

UPDATE

And there is another way without introducing new methods or constructors:

 public class MyClass { private BitSet mask; public MyClass() { this(new BitSet(4) {{ set(0,3); }}); } public MyClass(BitSet mask) { this.mask = mask; } } 

An anonymous class is created by extending the BitSet and adding an instance initialization block, hence double curly braces .

+3
source

BitSet does not have a free interface, so something like new BitSet(4).set(0,3) does not work for BitSets. There are only static methods BitSet.valueOf (), but they are somewhat inconvenient to use. However, if you want a static configuration, you can simply create an instance of BitSet with the desired value, use BitSet.toLongArray (), print the values ​​of the array and create an instance of your BitSet. In your specific example, the default constructor could be:

 public MyClass() { this(BitSet.valueOf(new long[]{7})); } 

As for the general part of the question: it will only work if you have a β€œsetter” that returns the current object, which will allow you to bind calls. So for your own classes, you can do something like this:

 public class A { private int num; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public A withNum(int num) { setNum(num); return this; } } 

If you used this in the constructor, for example, using BitSet, you can do this(new A().withNum(4));

Free interfaces are pretty popular (for example, the AWS SDK has this everywhere), only JDK objects usually don't have them.

+2
source

No; this should be done as a separate call, which will be made after the completion of the construction of the facility. The only way to do this on one line in your situation is if the return method type was BitSet and the method returned the instance it was called on, in which case you could do

 this(new BitSet(4).set(0, 1)); // Doesn't actually work 

Unfortunately, set() is void , so you cannot do this.

0
source

Source: https://habr.com/ru/post/1247762/


All Articles