Reputation: 740
When creating the Racing class in ApplicationTest, I want to hand over the FixNumberBehavior class to the argument.
As shown below, to pass the argument to initialize FixNumberBehavior, but cannot pass the class field value to the static block.
The error message is as follows.
Variable 'isMove' might not have been initialized
FixNumberBehavior.java
public class FixNumberBehavior implements CarMoveBehavior {
private final boolean isMove;
private static FixNumberBehavior fixNumberBehavior;
static {
fixNumberBehavior = new FixNumberBehavior(); //error
}
public FixNumberBehavior(final boolean isMove) {
this.isMove = isMove;
}
@Override
public boolean moveBehavior() {
return isMove;
}
}
Racing.java
public class Racing {
private List<Car> cars;
private CarMoveBehavior carMoveBehavior;
public Racing(List<Car> cars, final CarMoveBehavior carMoveBehavior) {
this.cars = cars;
this.carMoveBehavior = carMoveBehavior;
}
public List<Car> getCars() {
return cars;
}
public void drive() {
cars.stream()
.forEach(car -> racingCondition(car));
}
private void racingCondition(Car car) {
if (carMoveBehavior.moveBehavior()) {
car.moveForward();
}
}
}
ApplicationTest
@ParameterizedTest
@CsvSource({"a,aa,aaa"})
void fixRandomNumberTest(String one, String two, String three) {
final List<Car> cars = Arrays.asList(new Car(one), new Car(two), new Car(three));
Racing racing = new Racing(cars, new FixNumberBehavior(true));
racing.drive();
racing.drive();
assertAll(
() -> assertThat(cars.get(0).getStep()).isEqualTo(2),
() -> assertThat(cars.get(1).getStep()).isEqualTo(2),
() -> assertThat(cars.get(2).getStep()).isEqualTo(2)
);
}
How can I initialize an object in the static block?
Upvotes: 0
Views: 112
Reputation: 124275
I am not sure why you want to overcomplicate things by
FixNumberBehavior
will set isMove
to true or false.isMove
from being final
to being static
. Those two keywords have different purpose:
final
prevents reassigning new value to itstatic
makes this field a class field, not instance field, so even if you create two instances of FixNumberBehavior
there will be only one isMove
variable which they both will use (so you can't preserve in one instance state like isMove=true
and in other state isMove=false
).What you are looking for is probably simply
public class FixNumberBehavior implements CarMoveBehavior {
private final boolean isMove;
private static FixNumberBehavior fixNumberBehavior = new FixNumberBehavior(true);
//set value you want here ^^^^
public FixNumberBehavior(final boolean isMove) {
this.isMove = isMove;
}
@Override
public boolean moveBehavior() {
return isMove;
}
}
Upvotes: 1
Reputation: 740
I solved it by attaching static to the field.
Objects created in the static block are not identified when compiling. Therefore, the argument value to be transferred to the object you create in the static block must also be processed statistically.
package racingcar.model.domain;
public class FixNumberBehavior implements CarMoveBehavior {
private static boolean isMove;
private static FixNumberBehavior fixNumberBehavior;
static {
fixNumberBehavior = new FixNumberBehavior(isMove);
}
private FixNumberBehavior() {
}
public static FixNumberBehavior getInstance(){
return fixNumberBehavior;
}
public FixNumberBehavior(final boolean isMove) {
this.isMove = isMove;
}
@Override
public boolean moveBehavior() {
return isMove;
}
}
Upvotes: -1
Reputation: 5165
The problem is FixNumberBehavior
has a final
field that must be set in the constructor, or in an assignment on the field definition line.
While there is a constructor that takes a value for that field, the static block is not using that constructor, but instead a no-arg constructor.
Pass the value for that final field (isMove
) in the new
statement.
Upvotes: 1