9
I was making a code with Reflection in Java 8 when I came across a strange behavior - A ArrayIndexOutOfBoundsException
unexpected. Based on this, I decided to create a minimal, complete and verifiable example.
First note this code:
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
public class BuggyReflection {
public class Test {
public Test(Class k) {
}
}
public static void main(String[] args) throws Exception {
for (Constructor<?> ctor : Test.class.getConstructors()) {
for (Parameter p : ctor.getParameters()) {
System.out.println(p.getParameterizedType());
}
}
}
}
Here’s the way out:
class BuggyReflection
class java.lang.Class
Now, when I change the parameter type of the constructor of Class
for Class<?>
:
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
public class BuggyReflection {
public class Test {
public Test(Class<?> k) {
}
}
public static void main(String[] args) throws Exception {
for (Constructor<?> ctor : Test.class.getConstructors()) {
for (Parameter p : ctor.getParameters()) {
System.out.println(p.getParameterizedType());
}
}
}
}
Then an unexpected exception occurs:
java.lang.Class<?>
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at java.lang.reflect.Parameter.getParameterizedType(Parameter.java:201)
at BuggyReflection.main(BuggyReflection.java:14)
Am I doing something wrong? I see no point in making this mistake.
Digging a little deeper with this code:
import java.lang.reflect.Constructor;
import java.util.Arrays;
public class BuggyReflection {
public class Test {
public Test(Class k) {
}
}
public static void main(String[] args) throws Exception {
for (Constructor<?> ctor : Test.class.getConstructors()) {
System.out.println(Arrays.toString(ctor.getGenericParameterTypes()) + ctor.getParameters().length);
}
}
}
Here is the output, demonstrating that for the JVM there are two parameters in the constructor (since it is a non-static internal class):
[class BuggyReflection, class java.lang.Class]2
Now, if I change the Class
for Class<?>
:
import java.lang.reflect.Constructor;
import java.util.Arrays;
public class BuggyReflection {
public class Test {
public Test(Class<?> k) {
}
}
public static void main(String[] args) throws Exception {
for (Constructor<?> ctor : Test.class.getConstructors()) {
System.out.println(Arrays.toString(ctor.getGenericParameterTypes()) + ctor.getParameters().length);
}
}
}
The result is inconsistent to say the least:
[java.lang.Class<?>]2
Here are the versions of java and javac I’m using:
C:\projetos>javac -version
javac 1.8.0_25
C:\projetos>javac -fullversion
javac full version "1.8.0_25-b18"
C:\projetos>java -version
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
C:\projetos>java -fullversion
java full version "1.8.0_40-b25"
I am strongly inclined to believe that this is a bug in Java, but I would like to know if I am actually doing something wrong or if this exception is somehow foreseen (I found nothing about it in the documentation).
I think it’s really bug. With the
getType()
works normal.– Franchesco