build failed: source value * is obsolete and will be removed in a future release
这其实只是一个警告,但是这意味着有些新特性、新版本的问题可能是由于源码编译版本导致。
该问题具体的低层原因不详,直接原因是Java Compiler 字节码版本太低。
解决方案:
Settings -> Build, Execution, Deployement -> Compiler -> Java Compiler -> Module Target bytecode version,将此处目标字节码版本提升到合适的版本。比如说这里设为1.7时会出现JUnit5单元测试构建失败。改为11或17后通过。
参考自Removing warning messages on IntelliJ IDEA while building Java project
警告示例:
Warning:java: source value 1.5 is obsolete and will be removed in a future release
Warning:java: source value 7 is obsolete and will be removed in a future release
具体场景是JUnit5单元测试构建失败,因此过不去。
代码附下,这里面其实只有一个位置会因为字节码版本过不去,原因可能是编译过程的字节码优化导致的。
public class Evaluate {
public static void main(String[] args) {
Deque ops = new ArrayDeque<>();
Deque vals = new ArrayDeque<>();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String s = scanner.next();
switch (s) {
case "(":break;
case "+":
case "-":
case "*":
case "/":
case "sqrt":
ops.push(s);
break;
case ")":
String op = ops.pop();
double v = vals.pop();
switch (op) {
case "+":
v = vals.pop() + v;
break;
case "-":
v = vals.pop() - v;
break;
case "*":
v = vals.pop() * v;
break;
case "/":
v = vals.pop() / v;
break;
case "sqrt":
v = Math.sqrt(v);
}
vals.push(v);
break;
default:
vals.push(Double.parseDouble(s));
}
}
System.out.println(vals.pop());
}
}
public class EvaluateTest {
@Test
public void test() {
try {
String input = "( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )";
Scanner scanner = new IOProxy(
"ch1.sec2.Evaluate",
"main",
String[].class
).invoke(input, (Object) null);
assertEquals(scanner.nextDouble(), 101.0);
input = "( ( 1 + sqrt ( 5.0 ) ) / 2.0 )";
scanner = new IOProxy(
"ch1.sec2.Evaluate",
"main",
String[].class
).invoke(input, (Object) null);
// 下面这一行会过不去
assertEquals(scanner.nextDouble(), 1.618, 0.1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class IOProxy {
private Class> targetClass;
private Method method;
public IOProxy(String className, String methodName, Class>... parameterTypes)
throws ClassNotFoundException, NoSuchMethodException {
targetClass = Class.forName(className);
method = targetClass.getMethod(methodName, parameterTypes);
}
private Scanner invoke(InputStream is, Object... args)
throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
InputStream sin = System.in;
PrintStream sout = System.out;
System.setIn(is);
ByteArrayOutputStream os = new ByteArrayOutputStream();
System.setOut(new PrintStream(os));
method.invoke(targetClass.getDeclaredConstructor().newInstance(), args);
System.setIn(sin);
System.setOut(sout);
return new Scanner(new ByteArrayInputStream(os.toByteArray()));
}
public Scanner invoke(String input, Object... args)
throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
return invoke(new ByteArrayInputStream(input.getBytes()), args);
}
public Scanner invoke(File input, Object... args)
throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, FileNotFoundException {
return invoke(new FileInputStream(input), args);
}
}