专业网站建设制作多少钱,企业信用,网站后台无法修改,广告设计接单网站在继续阅读实际文章之前#xff0c;我想感谢令人敬畏的Javaslang库的作者Daniel Dietrich #xff0c;他在我面前有了这个主意#xff1a; lukaseder尝试使用静态方法T#xff0c;T1扩展T#xff0c;... Tn扩展T Seq T toSeq#xff08;T1 t1#xff0… 在继续阅读实际文章之前我想感谢令人敬畏的Javaslang库的作者Daniel Dietrich 他在我面前有了这个主意 lukaseder尝试使用静态方法TT1扩展T... Tn扩展T Seq T toSeqT1 t1…Tn tn{…}从我的手机中…… — Daniel Dietrichdanieldietrich 2016年2月16日 逆变通用界 这一切都始于一条推文 您是否不想用Java编写T super T1T2…TN — Lukas Ederlukaseder 2016年2月16日 我想做一些事情像模式匹配一组类型的普通超级类型方法如下 T super T1 | T2 | ... | TN 请注意我真正想要的是对联合类型的支持而不是我最初声称的交集类型。 我为什么要这么做 因为它将很好地添加到jOOλ库中 该库具有Java的类型安全元组 class Tuple3T1, T2, T3 {final T1 v1;final T2 v2;final T3 v3;// Lots of useful stuff here
} 在元组中最好的是迭代所有属性的forEach()方法 tuple(1, a, null).forEach(System.out::println); 上面将简单地产生 1
a
null 现在此forEach()方法的参数类型是什么 它看起来像这样 class Tuple3T1, T2, T3 {void forEach(Consumer? super T1 | T2 | T3 c) {}
} 消费者将收到类型为T1 或 T2 或 T3的对象。 但是接受前面三种类型的普通超级类型的消费者也可以。 例如如果我们有 Tuple2Integer, Long tuple tuple(1, 2L);
tuple.forEach(v-System.out.println(v.doubleValue())); 上面的代码可以编译因为Number是Integer和Long的常见超级类型并且它包含doubleValue()方法。 不幸的是这在Java中是不可能的 Java当前仅对异常捕获块支持联合/求和类型 另请参见代数数据类型 您可以在其中编写以下内容 class X extends RuntimeException {void print() {}
}
class X1 extends X {}
class X2 extends X {}// With the above
try {...
}
catch (X1 | X2 e) {// This compiles for the same reasons!e.print();
} 但是不幸的是catch块是Java中唯一允许使用求和类型的位置。 这是Daniel巧妙而狡猾的解决方法发挥作用的地方。 我们可以编写一个静态方法来使用泛型执行某种“模式匹配”如果您斜视反之亦然 static T, T1 extends T, T2 extends T, T3 extends Tvoid forEach(Tuple3T1, T2, T3 tuple, Consumer? super T consumer
) {consumer.accept(tuple.v1);consumer.accept(tuple.v2);consumer.accept(tuple.v3);
} 现在可以安全地使用以上方法来推断T1T2和T3的公共超级类型 Tuple2Integer, Long t tuple(1, 2L);
forEach(t, c - {System.out.println(c.doubleValue());
}); 符合预期 1.0
2.0 这是有道理的因为泛型类型约束是简单地“相反地”指定的即当T1 extends T强制T1 extends T 强制是T super T1 … 如果你真的很quin眼-) 据说Daniel在Javaslang即将推出的模式匹配API中使用了此技术。 我们期待看到这一结果 翻译自: https://www.javacodegeeks.com/2016/02/ingenious-workaround-emulate-sum-types-java.html