以下代码在 JDK8 中编译得很好,但在 JDK7 中会出现类型不兼容错误。
List<List<? extends Number>> xs = Arrays.asList(Arrays.asList(0));
根据 this answer , List<List<? extends Number>>与 List<List<Integer>> 没有父类(super class)型关系.
在 Java 8 中有什么改变使这个任务有效?我也很难理解为什么它不能在 Java 7 中工作。
这两个语句使用 JDK7 编译时没有类型错误:
List<? extends Number> xs = Arrays.asList(0);
List<? extends List<? extends Number>> ys = Arrays.asList(Arrays.asList(0));
我觉得这两个在 JDK7 中都可以工作,但上面的原始示例却不能。当然,所有这些都可以在 JDK8 中工作。我认为要真正理解这里发生的事情,我需要理解为什么这些示例在 Java 7 中是合法的,但原始示例不是。
最佳答案
我相信这与 invocation contexts 有关和 widening reference conversion .
基本上,在该调用上下文中,参数的类型 0在 Arrays.asList(0)可以装箱到Integer然后扩大到Number .发生这种情况时,Arrays.asList(0)返回类型为 List<Number> .通过相同的过程,List<Number>可以转换为List<? extends Number>在用作外部 Arrays.asList(..) 的参数之前.
这等同于在 Java 7 中使用显式类型参数
List<List<? extends Number>> xs = Arrays.<List<? extends Number>>asList(Arrays.<Number>asList(0));
在 Java 7 中,表达式的类型是相同的,无论它在哪里使用,无论是独立表达式还是用于赋值表达式。
引入 Java 8 poly-expressions其中表达式的类型可能会受到表达式目标类型的影响。
例如,在下面的赋值表达式中
List<Number> numbers = Arrays.asList(1);
表达式的类型 Arrays.asList(1)是被调用方法的返回类型,它完全取决于泛型类型参数。在这种情况下,该类型参数将被推断为 Integer因为值 1可以转换为Integer通过装箱转换(基元不能与泛型一起使用)。所以表达式的类型是List<Integer> .
在 Java 7 中,这个赋值表达式不会编译,因为 List<Integer>不能分配给 List<Number> .这可以通过在调用 asList 时提供显式类型参数来解决。
List<Number> numbers = Arrays.<Number>asList(1);
在这种情况下,方法调用需要一个 Number第一个参数的参数和值 1满足那个。
在 Java 8 中,赋值表达式是一个 poly expression
A method invocation expression is a poly expression if all of the following are true:
The invocation appears in an assignment context or an invocation context (§5.2, §5.3).
If the invocation is qualified (that is, any form of
MethodInvocationexcept for the first), then the invocation elidesTypeArgumentsto the left of the Identifier.The method to be invoked, as determined by the following subsections, is generic (§8.4.4) and has a return type that mentions at least one of the method's type parameters.
作为一个多边形表达式,它会受到分配给它的变量类型的影响。这就是发生的事情。泛型 Number影响在调用 Arrays.asList(1) 时推断的类型参数.
请注意它在下面的例子中是如何不起作用的
List<Number> numbers = ...;
List<Integer> integers = ...; // integers is not a poly expression
numbers = integers; // nope
所以它不是协方差,但我们在某些地方得到了它的一些好处。
关于java - Java 7/8 泛型中嵌套通配符的可分配性差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24188824/
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
这道题是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[
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我正在尝试使用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
我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?