You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The TypeCache class generates the same descriptor for both Object[] and T[], causing incorrect association of a descriptor to a type, depending on which type populates the cache first.
Below code provides a test example
packagecom.strobel.reflection;
importorg.junit.Test;
importjava.util.Arrays;
importstaticorg.junit.Assert.assertEquals;
publicclassCustomTests {
@TestpublicvoidgenericParameterArrayTypesDoNotCollideInTypeCache() {
finalType<MyClass> c1 = Type.of(MyClass.class); // Load class with method having T[] parameterc1.getMethods(); // Load methods of class with method having T[] parameterfinalType<MyOtherClass> c2 = Type.of(MyOtherClass.class); // Load class with method having Object[] parameterfinalType<Object[]> objectArrayType = Types.Object.makeArrayType(); // Prepare Object[] type for comparisonfinalMethodInfomethod = c2.getMethod("getFirstOrNull", objectArrayType); // Load specific method having Object[] parameterfinalType<?> methodParameterType = method.getParameters().getParameterTypes().get(0); // Retrieve method parameter type (expected to be Object[])assertEquals(objectArrayType, methodParameterType); // The method parameter type should match the expected Object[], but will be T[]
}
privatestaticclassMyClass {
publicstatic <T> Iterable<T> enumerate(finalT[] items) {
returnArrays.asList(items);
}
}
privatestaticclassMyOtherClass {
publicstaticObjectgetFirstOrNull(finalObject... values) {
returnvalues.length > 0 ? values[0] : null;
}
}
}
Above code fails, unsless c2 method is loaded before c1 methods.
storing T[] as the equivalent type of [Ljava/lang/Object;. Once updated, it will not change anymore.
Due to this, the getFirstOrNull method above will incorrectly return that the array type used as parameter is T[], instead of Object[]
If I did not misunderstood the purpose of the TypeCache._map, it wants to store the most recent instance of a type, matching the descriptor and generic type arguments.
If so, in my opinion the descriptor could be changed like this:
But I am not really sure this is the expected behavior... could you explain a bit the _map purpose, expecially regarding generic types (both bounded and unbounded)?
The text was updated successfully, but these errors were encountered:
The
TypeCache
class generates the samedescriptor
for bothObject[]
andT[]
, causing incorrect association of a descriptor to a type, depending on which type populates the cache first.Below code provides a test example
Above code fails, unsless
c2
method is loaded beforec1
methods.The cause is that
procyon/Procyon.Reflection/src/main/java/com/strobel/reflection/TypeCache.java
Line 137 in fec0d7a
calls the
getInternalName
of anArrayType
, which returnsprocyon/Procyon.Reflection/src/main/java/com/strobel/reflection/ArrayType.java
Line 56 in fec0d7a
which is
[Ljava/lang/Object;
for bothObject[]
andT[]
.If the
T[]
is loaded first, it will then populate the cache_definitionMap
, as perprocyon/Procyon.Reflection/src/main/java/com/strobel/reflection/TypeCache.java
Line 96 in fec0d7a
storing
T[]
as the equivalent type of[Ljava/lang/Object;
. Once updated, it will not change anymore.Due to this, the
getFirstOrNull
method above will incorrectly return that the array type used as parameter isT[]
, instead ofObject[]
If I did not misunderstood the purpose of the
TypeCache._map
, it wants to store the most recent instance of a type, matching the descriptor and generic type arguments.If so, in my opinion the descriptor could be changed like this:
But I am not really sure this is the expected behavior... could you explain a bit the
_map
purpose, expecially regarding generic types (both bounded and unbounded)?The text was updated successfully, but these errors were encountered: