Java 这个复杂的泛型模式使Eclipse崩溃——我能让它工作吗?
(我正在使用EclipseLuna 4.4.0、JDK1.8.0_05) 我正在制作一个游戏,游戏世界的拓扑结构可以大致分解为Java 这个复杂的泛型模式使Eclipse崩溃——我能让它工作吗?,java,eclipse,generics,compiler-errors,Java,Eclipse,Generics,Compiler Errors,(我正在使用EclipseLuna 4.4.0、JDK1.8.0_05) 我正在制作一个游戏,游戏世界的拓扑结构可以大致分解为世界->关卡->平铺,其中平铺是一个小的地形单元。我设置了三个项目,其中一个为这些结构保存一些基类,另外两个是服务器和客户机,它们扩展了基础项目中的结构,以满足每个项目所需的其他内容。像这样: public class BaseLevel{ BaseLevel getNextLevel(){/* ...code... */} } public class Level
世界->关卡->平铺
,其中平铺是一个小的地形单元。我设置了三个项目,其中一个为这些结构保存一些基类,另外两个是服务器和客户机,它们扩展了基础项目中的结构,以满足每个项目所需的其他内容。像这样:
public class BaseLevel{
BaseLevel getNextLevel(){/* ...code... */}
}
public class Level extends BaseLevel{
Level getNextLevel(){
return (Level)super.getNextLevel();
}
}
基本项目:
public class BaseWorld{/* ...code... */}
public class BaseLevel{/* ...code... */}
public class BaseTile{/* ...code... */}
在服务器和客户端项目中:
public class World extends BaseWorld{/* ...extended code... */}
public class Level extends BaseLevel{/* ...extended code... */}
public class Tile extends BaseTile{/* ...extended code... */}
现在,在基本项目的许多部分中,都有返回基类的方法,但在服务器和客户端项目中,这通常意味着我必须重写这些方法并强制转换到子类型,因为子项目只使用子类型。像这样:
public class BaseLevel{
BaseLevel getNextLevel(){/* ...code... */}
}
public class Level extends BaseLevel{
Level getNextLevel(){
return (Level)super.getNextLevel();
}
}
这是一种需要维持的痛苦。我发现我可以使用泛型来解决其中一些问题,使用以下模式:
public class BaseLevel<Level extends BaseLevel<Level>>{
Level getNextLevel(){/* ...code... */}
}
public class Level extends BaseLevel<Level>{
//All sorted! getNextLevel() already returns this subclass type.
}
我猜当一个类的泛型被解析时,它必须去解析另一个类的泛型,然后陷入递归循环
提问时间:
这个错误是Eclipse编辑器有笔划,还是java编译器有笔划
以上内容在编辑器中并没有突出显示为编译器警告/错误-即使在技术上似乎有效,是否应该这样做
这种递归是无限深,还是非常深
在避免这个错误的同时,是否有可能实现我在这里试图实现的目标?(我想再次强调,这绝对不是一个好的模式,我只想知道它是否可以工作)Eclipse编辑器有笔画,还是java编译器有笔画? 本例中的Eclipse编辑器。下面的声明(当然是在不同的文件中)是有效的Java代码
public class BaseFoo<F extends BaseFoo<F,B>, B extends BaseBar<F,B>> {}
public class BaseBar<F extends BaseFoo<F,B> ,B extends BaseBar<F,B>> {}
public class Foo<F extends BaseFoo<F,B>,B extends BaseBar<F,B>> extends BaseFoo<F,B> {}
public class Bar<F extends BaseFoo<F,B>,B extends BaseBar<F,B>> extends BaseBar<F,B> {}
关于通用边界不匹配,这里有四个错误
让我们试着解决它
Foo<Foo<Foo,Bar>, Bar<Foo,Bar>> foo = new Foo<Foo<Foo,Bar>, Bar<Foo,Bar>>();
我希望这有帮助
闭幕词
不要继续。这是一条探索出的解决问题的可能途径。别再到这里来了 多么奇妙的怪物啊 在Eclipse4.4.1和JavaC1.8.045中,您的代码对我来说编译得很好,并且似乎工作正常。我认为在早期版本的Java8中,他们在类型检查的更微妙部分上遇到了一些问题;也许他们现在已经解决了 与jdpenix的观点相反,我认为这种设计可能是有用的。在静态类型控制和代码重用方面,我看不出他的建议设计怎么会有你的优势 例如:
public class ElegantMonstrosity {
public void m() {
SubWorld world = new SubWorld();
List<SubLevel> levels = world.getTiles();
SubLevel level = levels.get(0);
List<SubTile> tiles = level.getTiles();
SubLevel nextLevel = level.getNextLevel();
}
}
class BaseWorld<
Tile extends BaseTile<Tile, Level, World>,
Level extends BaseLevel<Tile, Level, World>,
World extends BaseWorld<Tile, Level, World>> {
List<Level> getTiles() { return null; }
}
class BaseLevel<
Tile extends BaseTile<Tile, Level, World>,
Level extends BaseLevel<Tile, Level, World>,
World extends BaseWorld<Tile, Level, World>> {
Level getNextLevel() { return null; }
List<Tile> getTiles() { return null; }
}
class BaseTile<
Tile extends BaseTile<Tile, Level, World>,
Level extends BaseLevel<Tile, Level, World>,
World extends BaseWorld<Tile, Level, World>> {
}
class SubTile extends BaseTile<SubTile, SubLevel, SubWorld> {}
class SubLevel extends BaseLevel<SubTile, SubLevel, SubWorld> {}
class SubWorld extends BaseWorld<SubTile, SubLevel, SubWorld> {}
公共类优雅怪物{
公屋{
子世界=新的子世界();
列表级别=world.getTiles();
子级别=级别。获取(0);
List tiles=level.getTiles();
subvel nextLevel=level.getNextLevel();
}
}
阶级基础世界<
地砖延伸至底层地砖,
水平延伸到基准水平,
世界扩展BaseWorld>{
List getTiles(){return null;}
}
类基级<
地砖延伸至底层地砖,
水平延伸到基准水平,
世界扩展BaseWorld>{
级别getNextLevel(){return null;}
List getTiles(){return null;}
}
类基瓦<
地砖延伸至底层地砖,
水平延伸到基准水平,
世界扩展BaseWorld>{
}
类子文件扩展了BaseTile{}
类子级扩展了基级{}
类子世界扩展了BaseWorld{}
感谢您的详细解释。我的结论和你的结论一样,我从来没有见过这样的事情,所以就像兔子洞一样深,哈哈。我不确定你要用Foo
来演示什么,但实际上可以在一个带有类型参数的上下文中实例化Foo
(可以彼此作为边界)。使用编译器在进行类型推断时使用的隐式类型参数:Foo-Foo=new-Foo()代码>。或者在具有类型参数的方法中:void m(){Foo-Foo=new-Foo();}
Foo<Foo<Foo,Bar>, Bar<Foo,Bar>> foo = new Foo<Foo<Foo,Bar>, Bar<Foo,Bar>>();
class World {
SomeCollection<Level> levels;
}
class Level {
SomeCollection<Tile> tiles;
}
class Tile { }
World gameWorld = new World.Builder().
.loadLevels(levelSource)
.loadTiles(tileset)
.build();
public class ElegantMonstrosity {
public void m() {
SubWorld world = new SubWorld();
List<SubLevel> levels = world.getTiles();
SubLevel level = levels.get(0);
List<SubTile> tiles = level.getTiles();
SubLevel nextLevel = level.getNextLevel();
}
}
class BaseWorld<
Tile extends BaseTile<Tile, Level, World>,
Level extends BaseLevel<Tile, Level, World>,
World extends BaseWorld<Tile, Level, World>> {
List<Level> getTiles() { return null; }
}
class BaseLevel<
Tile extends BaseTile<Tile, Level, World>,
Level extends BaseLevel<Tile, Level, World>,
World extends BaseWorld<Tile, Level, World>> {
Level getNextLevel() { return null; }
List<Tile> getTiles() { return null; }
}
class BaseTile<
Tile extends BaseTile<Tile, Level, World>,
Level extends BaseLevel<Tile, Level, World>,
World extends BaseWorld<Tile, Level, World>> {
}
class SubTile extends BaseTile<SubTile, SubLevel, SubWorld> {}
class SubLevel extends BaseLevel<SubTile, SubLevel, SubWorld> {}
class SubWorld extends BaseWorld<SubTile, SubLevel, SubWorld> {}