Arrayindexoutofboundsexception in Java 8 Parameter Reflection

Asked

Viewed 136 times

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).

  • 1

    I think it’s really bug. With the getType() works normal.

1 answer

5


It’s a Java bug:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5087240

To circumvent this bug, it is necessary to check whether the Constructor.getGenericParameterTypes() and the Constructor.getParameters() return arrays of different sizes. If this occurs, it is deduced that there is the implicit parameter of the missing outer class.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.