Java6 から Java8 に切り替えた後、問題に直面しています。
突然
java.lang.ClassCastException: java.base/java.lang.Integer は java.base/[Ljava.lang.Object; にキャストできません。
投げられます。
java.lang.reflect.Method.invoke(Object obj, Object... args) の varargs 引数にジェネリック型がマッチしていないようです。
コードがクリーンにコンパイルされ、実行時にのみ失敗するという事実により、これは私にとって非常に恐ろしいように見えます。ちなみに、java8でもソース/ターゲット定義が1.8以下ならコンパイル、実行成功!
理解を深めるために、小さな JUnit の例を用意しました。
public class GenericVarArgTest {
private static InnerClass myInnerClass;
@Test
public void testMethodInvocation()
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
doSomething();
System.out.println("Done .. all fine");
}
private void doSomething() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
myInnerClass = this.new InnerClass();
Method[] methods = myInnerClass.getClass().getMethods();
for (Method aktMethod : methods) {
if (aktMethod.getName().equals("printInteger")) {
// this will always be okay
// Integer myParam = getSomething();
// aktMethod.invoke(myInnerClass, myParam);
// this is just ok, for source / target level <= 1.7
aktMethod.invoke(myInnerClass, getSomething());
}
}
}
public static <T> T getSomething() {
final T result = (T) Integer.valueOf(1);
System.out.println("getSomething will return <T> : " + result);
return result;
}
public class InnerClass {
public String printInteger(final Integer aInteger) {
final String result = "Integer: " + aInteger;
System.out.println("Will return : " + result);
return result;
}
}
このpomを使用して、mavenでこの小さなテストをセットアップしました:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.test.java</groupId>
<artifactId>compiler-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>compiler test</name>
<description>Test the different compiler results </description>
<properties>
<java.version>1.8</java.version>
<project.java.source.level>${java.version}</project.java.source.level>
<project.java.target.level>${java.version}</project.java.target.level>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${project.java.source.level}</source>
<target>${project.java.target.level}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
このpomを実行すると
mvn clean compile test -Djava.version= 1.6
すべて順調。しかし、それを実行する
mvn clean compile test -Djava.version= 1.8
ClassCastException が発生します。
この動作が変更された理由のヒント。これはバグですか (または 1.8 までバグでしたか)? 説明をありがとう。