2

I am trying to cast an Object to HashMap<String, Object> in a neat, robust way. So far, every way I tried produces compiler warnings or errors. What is the proper way to do it? I have checked the internet and tried the following:

HashMap<String, Object> map = (HashMap<String, Object>) object;

The code above gives an unchecked conversion warning.

HashMap<String, Object> map = new HashMap<>();
if (object instanceof Map<String, Object>){
    map = (Map<String, Object>) object;
}

The code above gives an error, which says that objects cannot be compared to parameterized collections.

HashMap<String, Object> map = new HashMap<>();
if (object instanceof Map){
    Map genericMap = (Map) object;
    for (Object key : genericMap.keySet()){
        if (key instanceof String){
            map.put((String) key, genericMap.get(key));
        }
        else{
            throw new KeyException();
        }
    }
}

The code above yields a warning that "Map is a raw type. References to generic type Map<K,V> should be parameterized."

So what would be the proper way to do this? Thank you in advance!

3
  • 1
    You should use the object instanceof Map, and you can then cast as (Map<String, Object>). Just understand that there are no compile-time checks for the proper types in that map, so if it contains non-string keys then you may have some truly odd behavior. Commented Nov 1, 2022 at 15:02
  • 1
    What are you imagining "casting" means here? I suspect you're assuming that you should be able to class class Foo { int x; String y; }, take an object new Foo(1, "bar") and get a map with the entries "x"` mapped to 1 and "y" mapped to "bar". That's going to be much more complicated than a cast. If what you actually have is a Map<String, Object>, then you should do the unsafe cast and accept that that's the best that you're going to get. Commented Nov 1, 2022 at 15:03
  • 1
    IF the data comes from a persistent file (XML or .properties) you maybe could revert to the Properties class. Commented Nov 1, 2022 at 15:07

3 Answers 3

5

I am trying to cast an Object to HashMap<String, Object> in a neat, robust way. So far, every way I tried produces compiler warnings or errors. What is the proper way to do it?

There is no proper way to do it, supposing that "proper" implies both useful and type safe. Casting is the antithesis of type safety. Other than casts for arithmetic purposes, a safe cast is an unnecessary one.

There is not enough information to determine how to achieve what ultimately you are after, but generally speaking, that sort of thing revolves around writing true generic code instead of using type Object to funnel objects of unrelated type into the same methods, using instanceof to determine what you actually have, or casting.

Sign up to request clarification or add additional context in comments.

Comments

0

Just add @SuppressWarnings("unchecked") to your method

@SuppressWarnings("unchecked")
public void myMethod(){
    ...
}

and you should be able to use

HashMap<String, Object> map = (HashMap<String, Object>) object;

1 Comment

That doesn't solve the problem, it just asks the compiler (certain ones, anyway) not to report on it.
0

Below is the above code written such that you don't need @SuppressWarnings to compile cleanly. You can read up on "Unbounded Wildcards" to understand their proper use better. Java docs state they can be used when:

  • If you are writing a method that can be implemented using functionality provided in the Object class.
  • When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. In fact, Class<?> is so often used because most of the methods in Class do not depend on T.

I think both of these apply to your situation.

Code written with unbounded wildcards "?":

HashMap<String, Object> map = new HashMap<>();
if (object instanceof Map){
    Map<?, ?> genericMap = (Map<?,?>) object;
    for (Object key : genericMap.keySet()){
        if (key instanceof String){
            map.put((String) key, genericMap.get(key));
        }
        else{
            throw new KeyException();
        }
    }
}

Edited for clarity

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
Edited to state that my response demonstrated the use of "Unbounded Wildcards" to get the desired result. (No need for @SuppressWarnings and it compiles without warning)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.