这是 Java 中一个众所周知的习语。参见例如 this SO discussion .所以基本上要定义一个接口(interface),实现它的类需要有一个方法来与它们类的对象进行比较,你会这样做:
public interface IComparable<T extends IComparable<T>> {
public int compare(T item);
}
(注意:这显然是解决特定用例的一种不必要的复杂方法 - 请参阅 this post - 但我正在询问如何解释递归语法,不要介意特定应用程序)。
简而言之,这是一个递归定义,递归没有明显的结束,我看不出编译器/类型系统是如何做到这一点的。
此外,尝试用文字表达(“IComparable 是一个类,其实例可以与实现 IComparable 接口(interface)的类的对象进行比较”)会产生哲学/逻辑/数学中无法拥有的不合逻辑的循环定义但显然在编译器设计中是可行的 (!)。
此外,如果原始习语语法是可以接受的,那么似乎也可以说:
public interface IComparable<T extends IComparable<T extends IComparable<T>>> {
public int compare(T item);
}
...但是编译器显然只允许一个级别的extend。
任何人都可以阐明一些信息来帮助我理解这种递归通用定义吗?
基于已接受的答案 (BartoszKP),我认为我现在理解的是以下内容:
“递归”定义不应理解为(表示“定义取决于”关系的箭头):
[ IComparable<T> ] -------> [ IComparable<T> ]
...这是不合逻辑的(循环的),而是:
[ IComparable<T> ] ----------> [ list of methods (parameterized by T) ]
\ ^
\ |
\-------> [ type bound on T ]-------/
... 这并非不合逻辑,因此在编译器中是可行的。因此,换句话说,IComparable 的定义是根据它定义的方法列表和它在类型 T 上定义的界限给出的,而后者又取决于方法列表。所以,没有递归。
最佳答案
This is a well-known idiom in Java.
没有。它没有用,也不应该使用。除了 Enum(这是一种特殊情况,因为 enum 类型是编译器生成的),这种模式从未在官方 Java 库或任何官方 Java 文档的任何地方出现过。
类型变量上的泛型边界的目的是建立一种关系,以便泛型类或泛型方法中的代码可以使用该保证来执行某些操作而无需强制转换,这可能是不安全的。泛型边界应尽可能不受限制,同时仍然防止代码中的强制转换。
因此,绑定(bind) interface IComparable<T extends IComparable<T>> 的唯一合法目的是 1) 它实际上是一个类,而不是一个接口(interface)(接口(interface)没有代码,因此没有要避免的转换),以及 2) 类中的代码需要执行以下操作:使用一个方法从自身中获取 T,然后在该方法上调用一个需要 IComparable<T> 的方法。然后,保证 T 扩展 IComparable<T> 将允许在没有转换的情况下完成此操作。
我见过很多这种模式的使用,99%的情况下,他们不需要做上述操作。相反,99% 的时间,人们想要做的是以某种方式表达 T “等于” IComparable<T> ,上述模式不能保证(并且不可能用 Java 表达)。它只保证 T 扩展 IComparable<T>,但不保证 IComparable<T> 扩展 T。
大多数时候当人们使用这个模式时,他们将它用于一个他们在其中执行 (T)this 的类。需要强制转换的事实表明这可能是不安全的;其类型安全不受边界保证(不能保证 this(类型 IComparable<T>)扩展 T)。这实际上是不安全的;一个众所周知的例子是 class Foo extends IComparable<Foo>,然后是 class Bar extends IComparable<Foo>,因此 this(类型 Bar)不会扩展 T(Foo)。
因此,如果您看到该代码,几乎可以肯定它是在对它的作用产生误解的情况下编写的,并且几乎应该始终将其更改为:
public interface IComparable<T> {
public int compare(T item);
}
作为练习,我要求您找到一个片段,其中 interface IComparable<T extends IComparable<T>> 有效,而 interface IComparable<T> 无效。
关于java - 循环泛型 : interface IFoo <T extends IFoo <T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18553531/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll
我正在尝试使用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
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht