I have never encountered this sort of problem in Java before. All this code and the full project may be found at my GitHub. I have a Snowflake class with class hierarchy:
Snowflake extends SolidRectangle extends Movable extends Drawable extends Object
The following two code sections in my Snowflake class produce different graphical results in my game:
//In Snowflake class
public void decay()
{
age++;
color = randomSnowflakeColor();
if(age == 5)
{
super.remove();
Snowflake.Mempool.returnSnowflake(this);
}
}
and
//In Snowflake class
public void decay()
{
age++;
color = randomSnowflakeColor();
if(age == 5)
{
this.remove();
}
public void remove()
{
super.remove();
Snowflake.Mempool.returnSnowflake(this);
}
Neither SolidRectangle nor Movable overrides the remove method, but Drawable does, with the following implementation:
//In Drawable class
public void remove()
{
game.remove(this);
}
and GameContent game has the following implementation:
//In GameContent class
public synchronized void remove(Drawable drawable)
{
removeQueue.add(drawable);
}
I will spare you the details of removeQueue, suffice it to say that it is exactly what you expect.
As for Snowflake.Mempool, I know manual memory management isn’t usually part of a Java programmer’s day, but I found there was too much overhead in creating and garbage collecting these snowflakes, so I thought I would just reuse old snowflakes to avoid this overhead. Please don’t get distracted by this. My question is about how the two first code blocks could possibly be different, when they appear to be functionally equivalent.
So, how can the two first code block be producing different results?
While the same result is expected when calling
decay(), different behaviour of your class may result whenremove()is called from elsewhere in the code.Using your IDE, search for usages of the
remove()method and all may be revealed.