Losnikov
Losnikov

Reputation: 97

Type safety Hashtable

I am deserializing a Hashtable into a Hashtable instance using casting and i get this warning: Type safety: Unchecked cast from Object to Hashtable<Date,String>.

The code: list = ((Hashtable<Date,String>)oos.readObject());

Is there a way to solve this warning?

Upvotes: 3

Views: 144

Answers (2)

Anonymous
Anonymous

Reputation: 86324

Yes, there is.

    Object obj = oos.readObject();
    if (obj instanceof Hashtable) {
        list = ((Hashtable<?, ?>) obj);
        final Date dateKey = Date.from(Instant.parse("2019-05-01T00:00:00Z"));
        Object value = list.get(dateKey);
        if (value == null) {
            System.out.println("No value found for key " + dateKey);
        } else if (value instanceof String) {
            System.out.println("Value read from list was " + value);
        } else {
            System.out.println("list contained unexpected value type " + value.getClass());
        }
    } else {
        System.out.println("Unexpected type read: " + obj.getClass());
    }

There are two steps:

  • Check that the object read from oos is a Hashtable (BTW a very old class that we’re generally not using anymore).
  • Check that the Hashtable contains Date keys and String values (BTW Date is another very old class that we’re generally not using anymore).

At runtime we can check whether the object read from oos is a Hashtable through obj instanceof Hashtable, but due to the way Java generics work we cannot check whether is is a Hashtable<Date, String>. Therefore we just cast to Hashtable<?, ?>. The compiler can see the instanceof check and will not issue any warning because of this cast.

The get method of the Hashtable accepts any Object as argument (for historical reasons), so there is no problem passing a Date to it. Our second check is of the value returned from get: we want to know whether this is a String as expected. If it is, we can safely cast to String (not shown in the snippet).

If the Hashtable didn’t contain a mapping for the Date provided, get returns null. This in turn might either be because the Hashtable key type was not Date as expected or simply because our particular Date was not present as a key.

Upvotes: 1

GhostCat
GhostCat

Reputation: 140525

Simple answer: no, there isn't.

You see, the signature of that method says: it returns Object:

public final Object readObject()

Thus you must cast here. And thus there is no other way than suppressing the warning.

And there is also no other way. Keep in mind: the idea is that you can write any kind of java object into such streams. And thus you can "pull" any kind of object from it, too. Thus Object is the only return type that makes sense here.

Of course, with Java generics, the result could be some T, or some T that is further restricted. But then that would still be compile time only, with zero guarantees that things turn out as expected at runtime.

Upvotes: 7

Related Questions