Reputation: 11
I am quite new to Java, and I am constantly looking for ways to improve my code. But I don't seem to get this, if it is even possible to do.
Let's say I have this code (I edited out the irrelevant parts, so the code might seem weird):
public class NewBody {
public static int distanceScale = 5;
public int x, y;
public float xMeter = x * distanceScale;
public float yMeter = y * distanceScale;
public NewBody(int x, int y){
this.x = x;
this.y = y;
}
public void pixToMeter(){
this.xMeter = distanceScale * this.x;
}
If I don't call pixToMeter() and just try to use "instance.xMeter" directly, it just returns the vaulue 0, even though I've already set the x variable in the constructor.
So my question is: Is there a way to properly set variables without calling a method to do it? It seems highly unneccessary since I am not even passing a parameter to it.
Sorry for my poor english, I hope you understand what I am trying to say.
Upvotes: 1
Views: 382
Reputation: 109547
The initialisation of xMeter is done when x is still zero.
This is what actually happens:
public NewBody(int x, int y) {
// All fields are zeroed: 0, null, 0.0.
super(); // Object constructor, as Object is the parent class.
// Those fields that are initialized:
xMeter = this.x * distanceScale; // 0.0f * 5
yMeter = this.y * distanceScale;
// The rest of the constructor:
this.x = x;
this.y = y;
}
For a depending value:
public final void setX(int x) {
this.x = x;
xMeter = this.x * distanceScale;
}
And to apply the DRY principle (Don't Repeat Yourself): one could drop the initialisation of xMeter and call setX(x) in the constructor instead.
When called in the constructor it is important to make setX
final, that is: not overridable.
Upvotes: 4
Reputation: 13483
As others have mentioned, when the xMeter
is initialized, the constructor is not called yet and x
is still 0
, so the value of xMeter
is 0
as well.
To change that, you must update xMeter
's value once x
is initialized in the constructor, like so:
public NewBody(int x, int y){
this.x = x;
this.y = y;
// update x and y meter
xMeter = x * distanceScale;
yMeter = y * distanceScale;
}
However, you mentioned how you want xMeter
to update every time x
is changed as well. As it stands with your current code, that will not happen. However, a suggestion of mine would be to create a method to change the value of x
(and y
as well) and in those methods, also update the values of xMeter
and yMeter
. That way, whenever you want to change x
, call the methods and it will update your other values too.
Try adding these methods and changing your constructor to this:
// called setter methods
public void setX(int x) {
this.x = x;
this.xMeter = x * distanceScale;
}
public void setY(int y) {
this.y = y;
this.yMeter = y * distanceScale;
}
// constructor
public NewBody(int x, int y){
setX(x);
setY(y);
}
Upvotes: 1
Reputation: 11072
The source of the problem is here:
public float xMeter = x * distanceScale;
The issue is that you're initializing this instance variable outside the constructor. As a result, since x
is initialized to 0, the result of your multiplication is also 0.
If you need xMeter
and yMeter
initialized to a value based on x
or y
, simply declare them as you did the other fields:
public int xMeter;
And initialize their values in the constructor:
public newBody(int x, int y){
// initialize x and y ...
this.xMeter = x * distanceScale;
Upvotes: 2