- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在学习 Java 8 的特性,到目前为止已经成功实现了它们,但我最新的代码引发了两个问题。
第一个问题可以通过强制转换来解决,但是这里不应该发生这种情况,因为类型继承应该是健全的;这是在接受单参数构造函数参数时,其中构造函数是 Function FunctionalInterface 方法引用。
相关问题是,如果在调用方法引用时将此类型用作构造函数参数的类型,则在使用方法引用填充映射时,Java 无法将泛型参数的具体声明子类型解析为有效。
下面的代码使用分离的接口(interface)继承树、接口(interface)规范和接口(interface)实现,用于两种类型的对象 Node 和 Edge。
边有通用参数来定义创建方法引用时指定的开始节点和结束节点。
节点和边都可以有自定义子类型,它们有一个由实现子类型实现的派生接口(interface)(子类型)。
节点包含作为集合的关系,可以是具体节点引用或具体边引用。 (startNode 应该匹配持有边集的父对象,但作为边的成员是必需的,这是我无法控制的)
为避免大量重复代码,通过操作界面进行访问
Operations 接口(interface)也有一个单独的接口(interface)和具体实现,并且有两种类型(Node 和 Edge)来支持 Edge 所需的泛型,一种是为每个具有关系的 ImplExtendedNode 中的每个关系集创建的。
这个修改是将创建者方法引用的存储移回知道使用哪些具体类型并有权访问Sets的类,而不是将自定义方法引用传递给每个Operations构造函数,然后传递它返回调用。
该问题与 Edge(构造函数)方法引用非常相关,无法正确解析类型是否有效并满足泛型类型约束的要求。
该系统是批处理过程的一部分。我已经去掉了所有不重要的东西,我真的很感激帮助我了解更多关于泛型和 Java 8 的新特性的信息,以帮助任何理解我出错的人。
//Node Interfaces
public interface Node {
...
}
public interface DefaultNode extends Node {
...
public <S extends Object & DefaultNode> Optional<S> createRelationship(NodeOperations nodeOps);
public <R extends Object & DefaultEdge, T extends Object & DefaultNode> Optional<R> createRelationship(EdgeOperations edgeOps);
...
}
//Edge Interfaces
public interface Edge<S extends Object & Node, T extends Object & Node> {
...
}
public interface DefaultEdge<S extends Object & Node, T extends Object & Node> extends Edge<S, T> {
...
}
//Implementation Classes
//(base objects)
public abstract class ImplNode implements Node {
...
}
public abstract class ImplEdge<S extends Object & Node, T extends Object & Node> implements Edge<S, T> {
...
//constructor(s)
public ImplEdge(S s) {
...
}
...
}
//(provide basic functions)
public abstract class ImplDefaultNode extends ImplNode implements DefaultNode {
//holds method reference to custom node/edge constructors in child implementation class definitions (multiple per class)
protected Map<NodeOperations, Supplier> nodeSuppliers;
protected Map<EdgeOperations, Function> edgeSuppliers;
//this works fine
@Override
public <S extends Object & DefaultNode> Optional<S> createRelationship(NodeOperations nodeOps) {
...
Supplier<S> f = this.nodeSuppliers.get(nodeOps);
S relationship = f.get();
...
}
//issue one, cannot automatically cast type of "this" to expected type of T in f.apply(this) - I know this should be possible in most cases and usually points to an issue with the code
@Override
public <R extends Object & DefaultEdge, T extends Object & DefaultNode> Optional<R> createRelationship(EdgeOperations edgeOps) {
...
Function<T, R> f = this.edgeSuppliers.get(edgeOps);
R relationship = f.apply(this);
...
}
}
public abstract class ImplDefaultEdge<S extends Object & Node, T extends Object & Node> extends ImplEdge<S, T> implements DefaultEdge<S, T> {
private S startNode;
private T endNode;
...
}
//(provides custom extensions which rely on ImplDefaultNode)
//custom implementation of interface derived and defined from DefaultNode
public class ImplExtendedNode extends ImplDefaultNode implements ExtendedNode {
...
private Set<DifferentImplExtendedNode1> nodeRels1;
...
private Set<ImplExtendedEdge<ImplExtendedNode, DifferentImplExtendedNode2>> edgeRels1;
//this works when called via create function in superclass through generic map lookup
@Override
public NodeOperations morphNodeRels1() {
...
this.nodeSuppliers.put(i, DifferentImplExtendedNode1::new);
...
}
//this throws compiler error -
//Cannot convert java.lang.Object to ImplExtendedNode
//It only works if the first generic type is ImplNode, or ImplDefaultNode I think)
@Override
public EdgeOperations morphEdgeRels1() {
...
this.edgeSuppliers.put(i, ImplExtendedEdge<ImplExtendedNode, DifferentImplExtendedNode2>::new);
...
}
}
最佳答案
您的问题与 Java 8 无关,它们源于对某些泛型声明含义的根本误解。
如果您定义带有类型参数的类或方法,则意味着使用这些类或方法的代码可以使用它们和替换这些参数的任意类型,并且您的通用代码将独立于使用代码实际上已经选择了类型参数。
你定义一个接口(interface),如:
public interface DefaultNode extends Node {
...
public <S extends Object & DefaultNode> Optional<S>
createRelationship(NodeOperations nodeOps);
public <R extends Object & DefaultEdge, T extends Object & DefaultNode> Optional<R>
createRelationship(EdgeOperations edgeOps);
...
}
第一个方法 promise 返回 Optional<WhatEverTheCallerChooses>
只要调用者选择的类型是 DefaultNode
的子类型.当然,那是行不通的。为了证明这一点,以下代码编译无误:
public static void demonstrating(DefaultNode n, NodeOperations o) {
abstract class FooBar implements DefaultNode {}
Optional<FooBar> opt = n.createRelationship(o);
if(opt.isPresent()) {
FooBar fb = opt.get();
}
}
createRelationship
的通用签名方法 promise 以某种方式返回 FooBar
的具体子类甚至不知道本地的类(class)。当然,在这种情况下,它总是可以返回一个空的可选值,但是唯一有效的实现是不返回任何内容的方法是没有意义的。
第二种方法甚至添加了另一个类型参数,T
,它没有出现在方法签名的其他地方,这使得它完全无用。您尝试在方法实现中使用它表明您不了解类型参数是调用者与方法实现之间契约的一部分:
@Override
public <R extends Object & DefaultEdge, T extends Object & DefaultNode> Optional<R>
createRelationship(EdgeOperations edgeOps) {
...
Function<T, R> f = this.edgeSuppliers.get(edgeOps);
R relationship = f.apply(this);
...
}
自 R
和 T
是方法的类型参数,调用者 决定用什么实际类型来代替它们。 edgeSuppliers.get
返回原始类型 Function
所以编译器接受对 Function<T, R>
的赋值尽管这是完全错误的。您不知道调用者为 T
选择了哪些实际类型和 R
所以你无法知道函数是否满足契约,见上文,T
可能是 FooBar
.
然后调用 f.apply(this)
,但是你怎么能期望它被编译器接受呢?如上图,T
可能是本地类型 FooBar
和你的 this
引用未指向 FooBar
的实例.当然,您的 map 不可能包含实际需要 FooBar
的函数。一个完全不同的上下文的实例,但这仅表明先前未经检查的操作已经是错误的。 T
可能是 FooBar
所以这个函数不能是Function<T,R>
.
但如前所述,T
根本不在方法声明中使用,因此在方法中使用它也没有任何意义。如果您断言所有函数都可以使用 this
在这个地方,它们应该可以分配给 Function<? super ImplDefaultNode, …>
并且你应该在你的类中使用适当的声明,包括 Map
的声明.但是,无法 promise 在调用时返回调用者希望的任何内容。你最好在这个地方没有任何类型参数并声明保证的最小值,例如一个Optional<Node>
.
关于Java 8 问题尝试在使用继承和泛型时添加 Function FunctionalInterface 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37966294/
我创建了一个用户可以添加测试的字段。这一切运行顺利我只希望当用户点击(添加另一个测试)然后上一个(添加另一个测试)删除并且这个显示在新字段中。 所有运行良好的唯一问题是点击(添加另一个字段)之前添加另
String[] option = {"Adlawan", "Angeles", "Arreza", "Benenoso", "Bermas", "Brebant
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在努力将 jQuery 滚动功能添加到 nav-tab (Bootstrap 3)。我希望用户能够选择他们想要的选项卡,并在选项卡内容中有一个可以平滑滚动到 anchor 的链接。这是我的代码,可
我正在尝试在用户登录后再添加 2 个 ui 选项卡。首先,我尝试做一个之后。 $('#slideshow').tabs('remove', '4'); $("#slideshow ul li:last
我有一个包含选择元素的表单,我想通过选择添加和删除其中一些元素。这是html代码(这里也有jsfiddle http://jsfiddle.net/txhajy2w/):
正在写这个: view.backgroundColor = UIColor.white.withAlphaComponent(0.9) 等同于: view.backgroundColor = UICo
好的,如果其中有任何信息,我想将这些列添加到一起。所以说我有 账户 1 2 3 . 有 4 个帐户空间,但只有 3 个帐户。我如何创建 java 脚本来添加它。 最佳答案 Live Example H
我想知道是否有一种有效的预制算法来确定一组数字的和/差是否可以等于不同的数字。示例: 5、8、10、2,使用 + 或 - 等于 9。5 - 8 = -3 + 10 = 7 + 2 = 9 如果有一个预
我似乎有一个卡住的 git repo。它卡在所有基本的添加、提交命令上,git push 返回所有内容为最新的。 从其他帖子我已经完成了 git gc 和 git fsck/ 我认为基本的调试步骤是
我的 Oracle SQL 查询如下- Q1- select hca.account_number, hca.attribute3, SUM(rcl.extended_amou
我正在阅读 http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingG
我正在尝试添加一个“加载更多”按钮并限制下面的结果,这样投资组合页面中就不会同时加载 1000 个内容,如下所示:http://typesetdesign.com/portfolio/ 我对 PHP
我遇到这个问题,我添加了 8 个文本框,它工作正常,但是当我添加更多文本框(如 16 个文本框)时,它不会添加最后一个文本框。有人遇到过这个问题吗?提前致谢。 Live Link: JAVASCRIP
add/remove clone first row default not delete 添加/删除克隆第一行默认不删除&并获取正确的SrNo(例如:添加3行并在看到问题后删除SrNo.2)
我编码this ,但删除按钮不起作用。我在控制台中没有任何错误.. var counter = 0; var dataList = document.getElementById('materi
我有一个类似数组的对象: [1:数组[10]、2:数组[2]、3:数组[2]、4:数组[2]、5:数组[3]、6:数组[1]] 我正在尝试删除前两个元素,执行一些操作,然后将它们再次插入到同一位置。
使用的 Delphi 版本:2007 你好, 我有一个 Tecord 数组 TInfo = Record Name : String; Price : Integer; end; var Info
我使用了基本的 gridster 代码,然后我声明了通过按钮添加和删除小部件的函数它工作正常但是当我将调整大小功能添加到上面的代码中时,它都不起作用(我的意思是调整大小,添加和删除小部件) 我的js代
title 323 323 323 title 323 323 323 title 323 323 323 JS $(document).keydown(function(e){
我是一名优秀的程序员,十分优秀!