I have a use-case where I want to log different Strings depending on the type of the Exception raised. To accomplish this, I wrote a Map which maps a Class to a String. And I am checking if the raised Exception is an instance of any of the Classes in the map, if it is I log the corresponding String stored with it.
Is using a Class as a key of a Map a bad idea? I am using SonarLint for static code analysis and it complains that I am using something as a key for a Map which does not implement Comparable. How bad is it? Is there a better approach to tackle my use case?
Sample code -
Map<Class<? extends Exception>, String> map = Map.of(A.class, "Log A", B.class, "Log B", C.class, "Log C");
map
.entrySet()
.stream()
.filter(entry -> entry.getKey().isInstance(raisedException))
.findFirst()
.ifPresentOrElse(
entry -> log.warn(entry.getValue()),
() -> log.warn("Unknown exception class: {}.", raisedException.getClass()));
SonarLint rule - https://rules.sonarsource.com/java/RSPEC-6411
Is using a Class as a key of a Map a bad idea?
Not at all, Map keys should always be a derived data type. Even though we are passing a Primitive data type it will be upcasted to the respective Wrapper type.
Is it ok to use something as a key for a Map which does not implement Comparable?
Comparable or Comparator are interfaces that are used on a class to ensure that the class is providing a comparison mechanism when a collection of the same is being sorted. This will come into the picture only when you are trying to sort your Map (TreeMap).
A few of the in-built classes are already implementing the above interfaces, but
Exceptionclasses won't usually implement it because they won't be used in a sorting scenario. So, you can ignore that warning, it is giving a warning for the possibility that if yourmapis initialized to aTreeMapit can cause a ClassCastException.PS: We will supply a reference of a class to a Map, we cannot supply a class to a Map (Class vs Reference)