Java 流#减少意外类型的结果,我做错了什么?
我有一个简单的Gradle项目: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' }
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();