Java 流#减少意外类型的结果,我做错了什么?

Java 流#减少意外类型的结果,我做错了什么?,java,java-stream,java-11,Java,Java Stream,Java 11,我有一个简单的Gradle项目: plugins { id 'java' id 'application' } repositories { mavenCentral() } sourceCompatibility = '11' targetCompatibility = '11' mainClassName = 'demo.Main' dependencies { compile 'net.bytebuddy:byte-buddy:1.9.13' }

我有一个简单的Gradle项目:

plugins {
    id 'java'
    id 'application'
}

repositories {
    mavenCentral()
}

sourceCompatibility = '11'
targetCompatibility = '11'

mainClassName = 'demo.Main'

dependencies {
    compile 'net.bytebuddy:byte-buddy:1.9.13'
}
package demo;

import java.awt.*;
import java.util.stream.*;
import net.bytebuddy.agent.builder.*;
import net.bytebuddy.matcher.*;

import static net.bytebuddy.matcher.ElementMatchers.*;

public class Main {
    public static void main(String[] args) {
        // This compiles
        new AgentBuilder.Default().
            type(nameStartsWith("com.demo").or(is(Point.class))
        );


        var typeSpec = Stream.of(nameStartsWith("com.demo"), is(Point.class)).reduce(ElementMatcher.Junction::or).orElseThrow();

        // This does not compile
        new AgentBuilder.Default().type(typeSpec);
    }   
}

项目中只有一个Java文件:

plugins {
    id 'java'
    id 'application'
}

repositories {
    mavenCentral()
}

sourceCompatibility = '11'
targetCompatibility = '11'

mainClassName = 'demo.Main'

dependencies {
    compile 'net.bytebuddy:byte-buddy:1.9.13'
}
package demo;

import java.awt.*;
import java.util.stream.*;
import net.bytebuddy.agent.builder.*;
import net.bytebuddy.matcher.*;

import static net.bytebuddy.matcher.ElementMatchers.*;

public class Main {
    public static void main(String[] args) {
        // This compiles
        new AgentBuilder.Default().
            type(nameStartsWith("com.demo").or(is(Point.class))
        );


        var typeSpec = Stream.of(nameStartsWith("com.demo"), is(Point.class)).reduce(ElementMatcher.Junction::or).orElseThrow();

        // This does not compile
        new AgentBuilder.Default().type(typeSpec);
    }   
}

我希望
Stream.of(nameStartsWith(“com.demo”)、is(Point.class)).reduce(ElementMatcher.Junction::or).orelsetrown()
生成与
type(nameStartsWith(“com.demo”).或(is(Point.class))
相同的类型,但它不会生成,并导致编译失败:

/code/compile-error/src/main/java/demo/Main.java:18: error: incompatible types: invalid method reference
                var typeSpec = Stream.of(nameStartsWith("com.demo"), is(Point.class)).reduce(ElementMatcher.Junction::or).orElseThrow();
                                                                                             ^
    method or in interface Junction<S> cannot be applied to given types
      required: ElementMatcher
      found: Junction<? extends NamedElement>,Junction<? extends NamedElement>
      reason: inference variable U has incompatible upper bounds CAP#2,CAP#1
  where S,U are type-variables:
    S extends Object declared in interface Junction
    U extends CAP#1 declared in method <U>or(ElementMatcher<? super U>)
  where CAP#1,CAP#2 are fresh type-variables:
    CAP#1 extends NamedElement from capture of ? extends NamedElement
    CAP#2 extends NamedElement from capture of ? extends NamedElement
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
/code/compile error/src/main/java/demo/main.java:18:错误:不兼容的类型:无效的方法引用
var typeSpec=Stream.of(nameStartsWith(“com.demo”),is(Point.class)).reduce(ElementMatcher.Junction::or).orelsetrow();
^
方法或接口内连接不能应用于给定类型
必需:ElementMatcher
发现:当您编写
类型(nameStartsWith(“com.demo”).或(is(Point.class))
时,方法调用
类型
为方法
提供上下文,后者为方法
is
提供上下文

ByteBuddy API利用了匹配器这一事实,具有很大的灵活性,因此能够检查X类型实例的匹配器也可以检查X的子类型实例

例如,签名的方法

<T extends TypeDefinition> ElementMatcher.Junction<T> is(Type type)
void type(ElementMatcher<? super TypeDescription> typeMatcher)
允许推断扩展两个匹配器类型的更具体类型
U
,因此如果使用

ElementMatcher.Junction<NamedElement> a = nameStartsWith("com.demo");
ElementMatcher.Junction<TypeDefinition> b = is(Point.class);
var combined = a.or(b);
new AgentBuilder.Default().type(combined);
将接受该类型的匹配器,因为
TypeDefinition
TypeDescription
的超类型


相反,当您通过

Stream.of(nameStartsWith("com.demo"), is(Point.class))

不可能利用匹配器的特殊性质;编译器必须为
ElementMatcher.Junction
ElementMatcher.Junction
找到一个通用的基类型,这将在
ElementMatcher.Junction结束。编译错误是什么?请阅读“如何创建”。然后使用链接改进您的问题(请勿通过评论添加更多信息)。否则,我们无法回答您的问题并帮助您。我已将问题的全部细节重写。请您打开关闭?
var typeSpec = Stream.<ElementMatcher.Junction<TypeDefinition>>of(
        nameStartsWith("com.demo"),
        is(Point.class))
    .reduce(ElementMatcher.Junction::or).orElseThrow();