本文介绍了在Java 8中返回泛型函数接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我想写一种功能工厂。它应该是一个函数,它被称为一次不同的策略作为参数。它应该返回一个函数,该函数根据参数选择这个策略中的一个,这由谓词来实现。 那么,为了更好的理解,最好看看 condition3 。 问题是,它没有编译。我认为,因为编译器无法弄清楚,函数接口 H 可以通过实现来实现。 没有泛型,它工作正常。 @FunctionalInterface public interface Finder< T,S> { Stream< S> findBest(T t); //有效代码 static< P,Q> Finder< P,Q> condition1(){ return p - >空值; } //有效的代码,但是当方法被调用时只选择其中一个H static< P,Q,H扩展Finder< P,Q>> ; H条件2(Pair< Predicate< P>,H> ... hs){ return hs [0] .getRight(); } //应该返回一个方法,当它用P 调用时,它会选择合适的H // //编译器抱怨: //该表达式的目标类型必须是功能接口 static< P,Q,H扩展Finder< P,Q>> H条件3(Pair< Predicate< P>,H> ... hs){ return p - > stream(hs).filter(pair - > pair.getLeft().test(p)) .findFirst() .map(Pair :: getRight) .map(h - > h.findBest(p))。orElseGet(Stream :: empty); } } 那么这里有什么问题?我可以解决它,如果它可能与Java:如何?解决方案看看你的方法的签名,并试图告诉什么确切的返回类型是: static Lambdas只能实现界面在编译时已知,但编译器不知道 H 的实际类型参数。 你的第一个方法是可行的,因为它返回lambda可以实现的类型 Finder< P,Q> ,你的第二个方法可以工作,因为它不使用lambda来实现返回类型 H扩展Finder< P,Q> 。 只有第三种方法试图为类型指定lambda表达式参数 H扩展Finder< P,Q> 。 A解决方案并不是让调用者自由地将特定的 Finder 子类型作为方法的返回类型: $ P $ Q $>静态< P,Q>条件3(Pair< Predicate< P>,H> ;. .. hs){ 请看下面的例子: final class HImpl实现了Finder< String,String> { public Stream< String> findBest(String t){ return null; //只是为了说明,我们从来没有真正使用过类} } ... HImpl x = Finder。< String,String,HImpl> condition3(); 考虑到您的原始方法签名,这个编译没有任何错误。但是如何使用lambda表达式 condition3 在这里提供一个 HImpl 的实例? I want to write kind of function factory. It should be a function, which is called once which different strategies as parameters. It should return a function, which selects one of this strategies dependent on the parameter, which is to be fulfilled by a predicate.Well, better look at condition3 for better understanding.The problem is, that it is not compiling. I think because the compiler can't figure out, that the functional interface H can be realized by the implementation.Without generics it is working fine. @FunctionalInterfacepublic interface Finder<T, S> { Stream<S> findBest (T t); // Valid code static <P, Q> Finder<P, Q> condition1 () { return p -> null; } // Valid code, but selects just one of the H's when the method is invoked static <P, Q, H extends Finder<P, Q>> H condition2 (Pair<Predicate<P>, H>... hs) { return hs[0].getRight (); } // Should return a method, which selects the appropiate H // whenever it is invoked with an P // Compiler complain: // The target type of this expression must be a functional interface static <P, Q, H extends Finder<P, Q>> H condition3 (Pair<Predicate<P>, H>... hs) { return p -> stream (hs).filter (pair -> pair.getLeft ().test (p)) .findFirst () .map (Pair::getRight) .map (h -> h.findBest (p)) .orElseGet (Stream::empty); }}So what's the problem here? Can I solve it and if it's possible with Java: how? 解决方案 Look at the signature of your method and try to tell what the exact return type is:static <P, Q, H extends Finder<P, Q>> H condition3(…Lambdas can only implement an interface known at compile-time. But the actual type argument for H is not known to the compiler.Your first method works because it returns the type Finder<P, Q> which the lambda can implement, your second works because it doesn’t use a lambda for implementing the return type H extends Finder<P, Q>.Only your third method attempts to specify a lambda expression for a type argument H extends Finder<P, Q>.A solution is not to give the caller the freedom to mandate a particular sub-type of Finder as the method’s return type:static <P, Q, H extends Finder<P, Q>> Finder<P, Q> condition3(Pair<Predicate<P>, H>... hs) {To illustrate what implications your original method signature has, look at the following example:final class HImpl implements Finder<String,String> { public Stream<String> findBest(String t) { return null; // just for illustration, we never really use the class }}…HImpl x=Finder.<String,String,HImpl>condition3();Given your original method signature this compiles without any error. But how ought the method condition3 provide an instance of HImpl here using your lambda expression? 这篇关于在Java 8中返回泛型函数接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-19 00:00