我一直在使用新的Eclipse Neon,我的一些代码开始直接给我错误.
这是很奇怪,我在第一,但后来我发现这里的霓虹灯欧洲法院(Eclipse的Java编译器)采用JDK 9提前释放编译器的态度.
我没有遇到该链接中的相同问题,而是我将在此解释的另一个问题.
这是一个测试类,它在Eclipse Neon,JDK 9编译器和JDK 8编译器(不是以前版本的Eclipse)中给出了编译错误.
public class Weird
{
private final Function<String, String> addSuffix =
text -> String.format( "%s.%s", text, this.suffix );
private final String suffix;
public Weird( String suffix )
{
this.suffix = suffix;
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于上面的代码,在所述误差线4为suffix是:
????????????????????????????????????????????????????????????
? Compiler ? Error ?
????????????????????????????????????????????????????????????
? ECJ ? Cannot reference a field before it is defined ?
? JDK 9 ? error: illegal forward reference …Run Code Online (Sandbox Code Playgroud) 当我用javap反汇编枚举时,enum的隐式构造函数参数似乎缺失了,我无法弄清楚为什么.
这是一个枚举:
enum Foo { X }
Run Code Online (Sandbox Code Playgroud)
我用这个命令编译和反汇编(在Java 8u60上):
javac Foo.java && javap -c -p Foo
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出:
final class Foo extends java.lang.Enum<Foo> {
public static final Foo X;
private static final Foo[] $VALUES;
public static Foo[] values();
Code:
0: getstatic #1 // Field $VALUES:[LFoo;
3: invokevirtual #2 // Method "[LFoo;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[LFoo;"
9: areturn
public static Foo valueOf(java.lang.String);
Code:
0: ldc #4 // class Foo
2: aload_0
3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #4 …Run Code Online (Sandbox Code Playgroud) 我正在创建一个java代理,用于对某些类进行一些字节码修改org.eclipse.jdt.core.JDTCompilerAdapter就是其中之一.我正在使用javassit来修改一些execute()方法org.eclipse.jdt.core.JDTCompilerAdapter.所以我在我的代理项目中包含了ecj(使用gradle)
compile group: 'org.eclipse.jdt.core.compiler' ,name: 'ecj', version :'4.3.1'
Run Code Online (Sandbox Code Playgroud)
因为我需要使用ecj中的一些类.
代理的目标是拦截对execute方法的调用,修改execute方法以向我的某些类添加一些调用,以触发一些处理.
我正在针对具有2个类的Simple Java项目测试代理.该项目使用ant构建并JDTCompilerAdapter用作编译器.
这是build.xml文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="TestProject">
<property file="build.properties" />
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.7"/>
<property name="source" value="1.7"/>
<path id="PClasspath">
<pathelement location="bin"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="init" name="build">
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/> …Run Code Online (Sandbox Code Playgroud) 考虑您想要使用包含以下方法签名来模拟接口:Mockito
public void doThis(Object o);
public void doThis(Object... o)
Run Code Online (Sandbox Code Playgroud)
我需要验证(doThis(Object o)而不是其他方法)是否已被调用一次。
首先,我认为下面的行可以解决问题:
verify(mock, times(1)).doThis(anyObject());
Run Code Online (Sandbox Code Playgroud)
doThis然而,这似乎在 Windows 上有效,但在 Linux 上却不起作用,因为在这种环境中,需要调用其他方法。
这是因为anyObject()参数似乎与两个方法签名都匹配,并且以或多或少不可预测的方式选择了一个方法签名。
如何强制Mockito 始终选择doThis(Object o)进行验证?
我知道Eclipse使用它自己的Java编译器(ECJ),它能够执行增量编译.从我发现的大多数读数来看,这个编译通常是由保存操作触发的,但这似乎与在输入单个单元/单词代码后几乎立即得到编译错误的错误反馈这一事实相匹配.我没有找到任何文档或文献说明这是什么粒度被触发(即每个单词,字母,行)?是否还有其他背景代码分析?虽然除了语法中的错误检测之外,我看不出它如何能够检测只能通过编译过程显示的语义错误.
在我们的代码库从 java 1.7 迁移到 1.8 的过程中,我们在几个代码位置收到一条错误消息“该方法......不适用于参数”,所有代码位置都遵循相同的泛型使用模式。
我们目前主要Eclipse Mars在 上使用(4.5.2) Windows 7,但也可以通过Neon(4.6)确认行为。Javac以及ecj1.7 合规级别都可以编译我们的代码而不会出错。
这是一个最小、完整且可验证的示例:
public class ComplexInterfaceTest {
public static class Foo {}
public interface Bar {
void print();
}
public static class SubFooBar extends Foo implements Bar {
public void print() {
System.out.println(this.getClass().getSimpleName());
}
}
public static class FooBar<T extends Foo & Bar> {
public static <T extends Foo & Bar> FooBar<T> makeFooBar() {
return new FooBar<>();
}
public void create(T …Run Code Online (Sandbox Code Playgroud) 问题设置包含三个java库(为了便于阅读,我删除了所有软件包名称,到处都使用了完整的限定名称):
external-lib:提供抽象类
public abstract class AbstractExternal {}
Run Code Online (Sandbox Code Playgroud)my-lib-A:提供课程
public class ClassA extends AbstractExternal {
public static final String FOO = "foo";
}
Run Code Online (Sandbox Code Playgroud)
external-lib 在my-lib-A的类路径中.
my-lib-B静态地从ClassA导入FOO:
import static ClassA.FOO;
public class ClassB {
private String foo = FOO;
}
Run Code Online (Sandbox Code Playgroud)
my-lib-A在my-lib-B的类路径中,但external-lib不是.
问题:该import static行产生以下错误:
The type AbstractExternal cannot be resolved. It is indirectly referenced from required .class files.
但是(1),将ClassB修改为
import ClassA;
public class ClassB {
private String foo = ClassA.FOO;
}
Run Code Online (Sandbox Code Playgroud)
编译器很高兴.
但是(2),当添加第二个抽象时,两个my-lib-A就好了
public class AbstractClassA extends …Run Code Online (Sandbox Code Playgroud) 谁能告诉我为什么以下代码无法编译但 lambda 版本可以:
是否有关于泛型类型推断的规则?我应该避免什么?
EntityLayerManager.refreshLayerRenderables(
wwd, this.networkNodeShapeLayer, nodeMap.values(),
MissionDetailUIConst::createNetworkNodeRenderable,
MissionDetailUIConst::updateNetworkNodeRenderable) // <<== FAILED
Run Code Online (Sandbox Code Playgroud)
EntityLayerManager.refreshLayerRenderables(
wwd, this.networkNodeShapeLayer, nodeMap.values(),
MissionDetailUIConst::createNetworkNodeRenderable,
(e, coll) -> MissionDetailUIConst.updateNetworkNodeRenderable(e, coll));
Run Code Online (Sandbox Code Playgroud)
EntityLayerManager.<EwmsVwNetworkNodeEntity, KolladaRoot>refreshLayerRenderables(
wwd, this.networkNodeShapeLayer, nodeMap.values(),
MissionDetailUIConst::createNetworkNodeRenderable,
MissionDetailUIConst::updateNetworkNodeRenderable)
Run Code Online (Sandbox Code Playgroud)
public static <E, R extends Renderable> int refreshLayerRenderables(WorldWindow wwd,
RenderableLayer renderableLayer, Collection<E> entityList,
Function<E, ? extends Collection<? extends R>> createRenderables,
BiPredicate<E, Collection<R>> updateRenderables);
public static Collection<KolladaRoot> createNetworkNodeRenderable(EwmsVwNetworkNodeEntity networkNode);
public static boolean updateNetworkNodeRenderable(EwmsVwNetworkNodeEntity networkNode, Collection<KolladaRoot> colladaRootCollection);
Run Code Online (Sandbox Code Playgroud) 根据JLS methodReferenceOfNullObject()调用时正确的行为是什么?
NullPointerException(Oracle Java Compiler)或指定供应商,result虽然o是null(Eclipse的Java编译器)
public void methodReferenceOfNullObject() {
Object o = nullReference();
Supplier<String> result = o::toString; // <-- point of interest
...
}
private Object nullReference() {
return null;
}
Run Code Online (Sandbox Code Playgroud)刚刚在 Eclipse 2021-09 上尝试了 JDK17,结果失败并显示java.lang.VerifyError,这本身并没有多大帮助。我追踪到一个 switch 语句,该语句获取从一个Map或另一个泛型类型中提取的值。如果我在 switch 语句中使用局部变量,一切都会按预期工作。
测试代码:
import java.util.HashMap;
import java.util.Map;
public class SwitchFail {
public static void main(String[] args) {
//doesnt work
Map<Integer, String> stringMap = new HashMap<>();
stringMap.put(1, "Test");
switch(stringMap.get(1)) {
}
//works
String plainString = "Test";
switch(plainString) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会引发以下错误:
Error: Unable to initialize main class SwitchFail
Caused by: java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
SwitchFail.main([Ljava/lang/String;)V @33: invokevirtual
Reason:
Type 'java/lang/Object' (current frame, stack[0]) is …Run Code Online (Sandbox Code Playgroud) ecj ×10
java ×9
eclipse ×3
java-8 ×3
eclipse-jdt ×2
generics ×2
.class-file ×1
ant ×1
eclipse-neon ×1
enums ×1
inheritance ×1
java-17 ×1
java-9 ×1
javap ×1
mockito ×1