Java – use interface classes as keys to get specific instance values?

I have the following test cases and can't retrieve values from the map:

package tests;

import java.util.HashMap;
import java.util.Map;

public class ClassTest {

    interface A {}
    interface B extends A {}
    interface C extends A {}

    class D implements B {}
    class E implements C {}

    public Classtest() {
        Map<Class<? extends A>,A> map = new HashMap<>();

        A d = new D();
        A e = new E();

        map.put(d.getClass(),d);
        map.put(e.getClass(),e);

        System.out.println(B.class.getSimpleName() + ": " + map.get(B.class));
        System.out.println(C.class.getSimpleName() + ": " + map.get(C.class));
    }

    public static void main(String[] args) {
        new Classtest();
    }

}

The expected outputs are:

B: D
C: E

The actual output is:

B: null
C: null

From what I know, "expected" will fail because b.class is not equal to d.class, even if class D is the implementation of B interface... So map Get (...) could not find the instance value of the related key (correct me if I'm wrong) the above situation wants to show my intention and "spirit" to complete

Is there a good / elegant choice that is useful, but also retains the spirit I am trying to do?

I'm updating the code to replace the enumeration type used as the "open collection" of class < T > As a type token, it is similar to valid Java, version 2, item 29

According to @ cking's request in the review, the part of this book quoting my method is quoted as follows

Please understand that I know the example in this book because it uses the value of a specific class (for example, string.class is an actual string rather than some hypothetical derived types from string). As mentioned, this simply promotes my method to see if my test example can work, Now I am looking for a solution or alternative to respect my "spirit" in test cases

Solution

Maybe not so elegant, but you can use reflection to get from key All values assigned by class:

System.out.println(B.class.getSimpleName() + ": " + getMapEntries(map,B.class));
System.out.println(C.class.getSimpleName() + ": " + getMapEntries(map,C.class));

....

private <T extends A> List<T> getMapEntries(Map<Class<? extends A>,A> map,Class<T> clazz) {
    List<T> result = new ArrayList<>();
    for (Map.Entry<Class<? extends A>,A> entry : map.entrySet()) {
        if (clazz.isAssignableFrom(entry.getKey())) {
            result.add((T) entry.getValue());
        }
    }
    return result;
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>