Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个复杂的泛型模式使Eclipse崩溃——我能让它工作吗?_Java_Eclipse_Generics_Compiler Errors - Fatal编程技术网

Java 这个复杂的泛型模式使Eclipse崩溃——我能让它工作吗?

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

(我正在使用EclipseLuna 4.4.0、JDK1.8.0_05)

我正在制作一个游戏,游戏世界的拓扑结构可以大致分解为
世界->关卡->平铺
,其中平铺是一个小的地形单元。我设置了三个项目,其中一个为这些结构保存一些基类,另外两个是服务器和客户机,它们扩展了基础项目中的结构,以满足每个项目所需的其他内容。像这样:

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> {}