下面的代码
class GenericCompilationFailureDemo {
List<? extends GenericCompilationFailureDemo> newList() {
return new ArrayList<GenericCompilationFailureDemo>();
};
void useList() {
List<GenericCompilationFailureDemo> list =
(List<GenericCompilationFailureDemo>) newList();
}
List<? extends Set<GenericCompilationFailureDemo>> newListOfSpecificSets() {
return new ArrayList<Set<GenericCompilationFailureDemo>>();
};
void useListOfSpecificSets() {
List<Set<GenericCompilationFailureDemo>> listOfSpecificSets =
(List<Set<GenericCompilationFailureDemo>>) newListOfSpecificSets();
}
List<? extends Set<? extends GenericCompilationFailureDemo>> newListOfSets() {
return new ArrayList<Set<? extends GenericCompilationFailureDemo>>();
};
void useListOfSet() {
List<Set<? extends GenericCompilationFailureDemo>> listOfSets =
(List<Set<? extends GenericCompilationFailureDemo>>) newListOfSets();
}
}
在 Sun JDK 1.6.0_20(在 Windows Vista 上为 64 位,但我认为这没有任何区别)下编译但在 Oracle JDK 1.7.0_01(相同平台)下导致以下编译失败:
[ERROR] src\main\java\GenericCompilationFailureDemo.java:[56,78] error: inconvertible types
请注意,useList 和 useListOfSpecificSets 中的前两个“扩展到特定类型”转换在 1.7.0_01 下仍然成功,所以这似乎与“双泛型扩展”有关。
有什么想法在 6 和 7 之间可能发生了变化,观察到的行为是符合规范还是错误?
编辑以回应 Sanjay 的评论:
@Sanjay:啊哈,有趣!这里是 java -version 的输出:
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
这里是 javac GenericCompilationFailureDemo.java 的结果(与上面相同的代码,带有 List、ArrayList 和 Set 的导入语句):
GenericCompilationFailureDemo.java:30: error: inconvertible types
(List<Set<? extends GenericCompilationFailureDemo>>) newListOfSets()
;
^
required: List<Set<? extends GenericCompilationFailureDemo>>
found: List<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends Set<? extends GenericCompilationFailureDemo> from capture of ?
extends Set<? extends GenericCompilationFailureDemo>
Note: GenericCompilationFailureDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
最佳答案
这显然是一个 javac7 错误。根据转换规则 [1] 应该允许它
其中一条规则允许缩小引用转换......然后是未经检查的转换
类型转换 List<A> => List<B>这条规则允许
List<A> => List // narrowing reference conversion
List => List<B> // unchecked conversion
但这还不是全部;该规范有进一步的规则来禁止像 List<String>=>List<Integer> 这样的转换,因为它们可证明是不同的参数化
类型。没有对象同时属于这两种类型,因此编译器认为最好不要允许这种明显的编程错误。 (你可以明确地绕过它 List<String>=>List=>List<Integer> )
虽然最后一条规则在这里不适用;所以它看起来像一个 javac7 错误。
为什么最后一条规则不适用:所以我们正在转换 List<? extends A>至 List<A> .这里捕获转换应用于 List<? extends A> [2] 所以我们实际上是在类型转换 List<T>至 List<A> , 其中T是一个上界为 A 的新类型变量.
问题是List<T>是否和 List<A>是可证明不同的参数化类型。我的理解是它是错误的(你的前两个例子必须是错误的才能编译)。自 T是一个类型变量,它可以取值使List<T>和 List<A>相同的参数化类型(即当 T=A 时)。此推理适用于任何类型 A .
[1] http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5
[2] http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#341306
关于java - 为什么要对 List< 进行泛型转换?将 Set..> 扩展到 List<Set..> 在 Sun JDK 6 上成功但在 Oracle JDK 7 上编译失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8637937/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用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
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[