2012-08-03 87 views
0

我从来没有在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程序员日的一部分,但我发现在创建和垃圾收集这些雪花时存在太多的开销,所以我想我会重复使用旧的雪花来避免这种开销。请不要因此而分心。我的问题是关于两个第一代码块如何在功能上等同时可能不同。

那么,两个第一代码块怎么会产生不同的结果呢?

+1

也许不同来自其他调用Snowflake.remove()的东西,它在这两种情况下有不同的行为? – 2012-08-03 03:43:51

+0

将日志记录在每个方法中,以便您可以观察以哪种顺序调用哪个方法。 – 2012-08-03 04:12:04

回答

1

在呼吁decay()时相同的结果的预期,可能会导致你的类的不同的行为时remove()在代码的其他地方调用。

使用您的IDE,搜索remove()方法的用法和所有可能会显示。

+0

谢谢! CollisionHandler将其识别为一个SolidRectangle并将其称为'((SolidRectangle)snowflake).remove()',因此它称为“Drawable”版本,而不是“Snowflake”版本的“代码。 – nullUser 2012-08-03 03:52:24

+0

实际上这不是问题...我添加了一个演员并验证了正确的版本正在被调用,但我仍然得到不同的行为。 – nullUser 2012-08-03 04:00:01

1

在评论你说的这个:

删除是由认识到这是一个SolidRectangle和人称其为((SolidRectangle)雪花)卸下摆臂(),所以它被称为可绘制版本,而不是所谓的CollisionHandler Snowflake版本的代码。

我不认为这是一个正确的解释。

你似乎在说这个:

Snowflake snowflake = ... 
((SolidRectangle) snowflake).remove(); 

会导致对雪花被称为覆盖SolidRectangle.remove()方法。这是不正确的。一旦该方法被覆盖,除Snowflake方法(或Snowflake超类型方法)调用super.remove()外,不能在Snowflake上调用该方法。

+0

你是对的,这不是问题。 – nullUser 2012-08-03 04:14:58

0

我想通了。问题是由于Snowflake.Mempool作为一个堆栈,最近被摧毁的雪花被用来制作新的雪花。我保留所有Drawable元素在ArrayList<Drawable>。这种组合导致某些雪花在ArrayList<Drawable>中出现两次,从而破坏了我的帧调整算法。切换到HashSet<Drawable>解决了问题。

相关问题