草庐IT

java - 这个复杂的泛型模式会导致 Eclipse 崩溃——我能让它工作吗?

coder 2024-03-20 原文

(我使用的是 Eclipse Luna 4.4.0,JDK 1.8.0_05)

我在做一个游戏,游戏世界的拓扑结构大致可以分解为World -> Level -> Tile,其中Tile是地形的一个小单元。我设置了三个项目,一个包含这些结构的一些基类,另外两个是服务器和客户端,它们扩展基础项目中的结构以获得每个项目需要的额外内容。像这样:

基础项目:

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

好吧,我有一个疯狂的想法,将上述模式弯曲到极限,并且能够在所有父类(super class)中的任何地方使用所有子类。现在我必须说,我绝不认可以下代码是好的编程,我只是有想法并尽可能地使用它,只是为了看看它会如何工作。不管怎样,我想出了以下怪诞的东西。

public class BaseWorld<Tile extends BaseTile<Tile, Level, World>
                      ,Level extends BaseLevel<Tile, Level, World>
                      ,World extends BaseWorld<Tile, Level, World>>{
  /* ...code... */
}

public class BaseLevel<Tile extends BaseTile<Tile, Level, World>
                      ,Level extends BaseLevel<Tile, Level, World>
                      ,World extends BaseWorld<Tile, Level, World>>{
  /* ...code... */
}

public class BaseTile<Tile extends BaseTile<Tile, Level, World>
                 ,Level extends BaseLevel<Tile, Level, World>
                 ,World extends BaseWorld<Tile, Level, World>>{
  /* ...code... */
}

现在,无论何时我需要从任何其他类返回任何类,我都可以在子项目中不使用任何类型转换!

很遗憾,不是,因为当 Eclipse 重建工作区时:

A stack overflow error has occurred.
You are recommended to exit the workbench. [...]

我想当一个类的泛型被解析时,它必须去解析另一个类的泛型,然后陷入递归循环。

提问时间:

这个错误是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> {}

以上内容不会在编辑器中作为编译器警告/错误突出显示 - 是否应该突出显示,即使它在技术上看起来是有效的?

它可能应该(好吧,好吧,好吧,我在这里开玩笑......)不。这是有效的 Java。只是……嗯……

这个递归可能无限深,还是非常深?

无限,我在这里猜测(稍后会详细介绍我的猜测)。

考虑尝试实例化 Foo 的实例。

继续,使用默认构造函数编写初始化程序。

Foo<Foo, Bar> foo = new Foo<Foo, Bar>();

关于通用边界不匹配,这里有四个错误。

让我们尝试解决它。

Foo<Foo<Foo,Bar>, Bar<Foo,Bar>> foo = new Foo<Foo<Foo,Bar>, Bar<Foo,Bar>>();

现在有 12 个错误。我们可以永远尝试初始化它。

是否可以在避免此错误的同时实现我在这里尝试的目标? (我再次强调,这绝对不是一个好的模式,我只是想知道它是否可以工作)

考虑以下基本结构:

class World {
    SomeCollection<Level> levels;
}

class Level {
    SomeCollection<Tile> tiles;
}

class Tile { }

为什么?

上面代码的基本结构比较喜欢composition over inheritance ,并且不使用泛型,除了一些内置的泛型集合类型。这为您提供的初始化样式的一个很好的例子是静态构建器,最终编写类似这样的东西来初始化 World:

World gameWorld = new World.Builder().
                 .loadLevels(levelSource)
                 .loadTiles(tileset)
                 .build();

希望对您有所帮助。

结束语

不要继续。这是可能解决您的问题的探索路径。不要再去这里了。

关于java - 这个复杂的泛型模式会导致 Eclipse 崩溃——我能让它工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25458729/

有关java - 这个复杂的泛型模式会导致 Eclipse 崩溃——我能让它工作吗?的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  4. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  5. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐