0
votes

I encountered a weird bug while doing JUnit test.

I'm using reflection to call a method I defined: MyReflectUtil.callMethod(testManager, "loadPermission"); Within the testManager there is an instance of ArrayMap. And loadPermission would call get() and put() on that instance.

This is the ArrayMap I defined:

public class ArrayMap<K, V> {
    HashMap<K, V> map = new HashMap<>();

    public void put(K key, V value) {
        map.put(key, value);
    }

    public V get(K key) {
        return map.get(key);
    }
}

Within the method loadPermission, I can call get() method, but when I call put() , I get the error:

java.lang.NoSuchMethodError: android.util.ArrayMap.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

What is this Ljava/lang/Object? When I log myArrayMapInstance.getClass().getDeclaredMethods(), I get:

public java.lang.Object android.util.ArrayMap.get(java.lang.Object), public void android.util.ArrayMap.put(java.lang.Object,java.lang.Object)

It does not have the letter L in front of java.lang.Object. Yet I can not explain why I can call get(), because it is fundamentally the same as put().

Can anyone help? Really appreciate it!

1
Concerning your question, "What is this Ljava/lang/Object?", see this thread. - yur
This class makes no sense to me at all, why would you name it ArrayMap<K, V>? You can't even define a constructor without getting compile errors on >? As far as I'm aware, class names can't have spaces? - yur
@yur, this is the Generic in Java. You can check the definition of java.util.List in java as an example. : ) - Helen Cui

1 Answers

1
votes

The Ljava/lang/Object; after the closing bracket is the expected method's return type:

java.lang.NoSuchMethodError: android.util.ArrayMap.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

Your call expects a method that returns something, but in your ArrayMap code, this put method is void.