Reputation: 97
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
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:
oos
is a Hashtable
(BTW a very old class that we’re generally not using anymore).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
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