逻辑上等同的代码产生不同的结果
我从来没有在Java中遇到过这样的问题。所有这些代码和完整的项目可以在my GitHub找到。我有一个Snowflake
类类层次结构:逻辑上等同的代码产生不同的结果
Snowflake extends SolidRectangle extends Movable extends Drawable extends Object
以下两个代码在我Snowflake
类板块产生在我的游戏不同的图形化结果:
//In Snowflake class
public void decay()
{
age++;
color = randomSnowflakeColor();
if(age == 5)
{
super.remove();
Snowflake.Mempool.returnSnowflake(this);
}
}
和
//In Snowflake class
public void decay()
{
age++;
color = randomSnowflakeColor();
if(age == 5)
{
this.remove();
}
public void remove()
{
super.remove();
Snowflake.Mempool.returnSnowflake(this);
}
无论SolidRectangle
也不Movable
覆盖remove
方法,但Drawable
确实与fol降脂实现:
//In Drawable class
public void remove()
{
game.remove(this);
}
和GameContent game
具有以下实现:
//In GameContent class
public synchronized void remove(Drawable drawable)
{
removeQueue.add(drawable);
}
我就饶你的removeQueue
的细节,我只想说,这是你期待什么。
至于Snowflake.Mempool
,我知道手动内存管理通常不是Java程序员日的一部分,但我发现在创建和垃圾收集这些雪花时存在太多的开销,所以我想我会重复使用旧的雪花来避免这种开销。请不要因此而分心。我的问题是关于两个第一代码块如何在功能上等同时可能不同。
那么,两个第一代码块怎么会产生不同的结果呢?
在呼吁decay()
时相同的结果的预期,可能会导致你的类的不同的行为时remove()
从在代码的其他地方调用。
使用您的IDE,搜索remove()
方法的用法和所有可能会显示。
在评论你说的这个:
删除是由认识到这是一个SolidRectangle和人称其为((SolidRectangle)雪花)卸下摆臂(),所以它被称为可绘制版本,而不是所谓的CollisionHandler Snowflake版本的代码。
我不认为这是一个正确的解释。
你似乎在说这个:
Snowflake snowflake = ...
((SolidRectangle) snowflake).remove();
会导致对雪花被称为覆盖SolidRectangle.remove()
方法。这是不正确的。一旦该方法被覆盖,除Snowflake
方法(或Snowflake
超类型方法)调用super.remove()
外,不能在Snowflake
上调用该方法。
你是对的,这不是问题。 – nullUser 2012-08-03 04:14:58
我想通了。问题是由于Snowflake.Mempool
作为一个堆栈,最近被摧毁的雪花被用来制作新的雪花。我保留所有Drawable
元素在ArrayList<Drawable>
。这种组合导致某些雪花在ArrayList<Drawable>
中出现两次,从而破坏了我的帧调整算法。切换到HashSet<Drawable>
解决了问题。
也许不同来自其他调用Snowflake.remove()的东西,它在这两种情况下有不同的行为? – 2012-08-03 03:43:51
将日志记录在每个方法中,以便您可以观察以哪种顺序调用哪个方法。 – 2012-08-03 04:12:04