问题
Say I have an ArrayList that I have cast to an ArrayList of objects. I know that all the objects that were in the ArrayList I cast were of the same type, but not what the type was.
Now, if the ArrayList is not empty, I could take one of the objects in it and use the instanceof operator to learn what the actual type is. But what of the case where the ArrayList is empty? How do I determine what type Object actually is then? Is it possible?
Edit: In retrospect, I suppose it doesn't strictly matter what type an empty ArrayList holds. I can discard the old one and construct a new empty ArrayList of the proper type I was looking for in the first place.
It's a bit messy, so if anyone has alternate suggestions for how to allow a large variety of potential types which may not share a relevant common superclass (Ex. Integer and ArrayList), I'm open to suggestions. The thing is, I have a class that will contain other classes specifically designed to be interchangably used within it. The contained classes can make assumptions as to the type, as they're the ones defining it. The surrounding class cannot make such assumptions, but must confirm that it is specifying the same type as the contained classes that have been slotted into it.
Thus my question, as the containing class is generic (the generic specifying what sort of type it is handling), but it must ensure the contained classes it was passed are returning and operating on the type that was specified to it (they are designed to be created separately and as such the fact that they match must be confirmed when they are slotted in, not at the time of their creation).
回答1:
Nope, type erasure makes sure of that.
回答2:
As Jeffrey mentioned, this is impossible due to magics of type erasure. Your best choice I guess is to add an additional case for the empty list:
if (list.isEmpty()) {
// process empty ...
} else {
Object o = list.get(0);
if (o instanceof Integer) {
List<Integer> integers = (List<Integer>) list;
// process Integer ...
} else if (o instanceof String) {
List<String> strings = (List<String>) list;
// process String ...
} // etc...
}
But beware! This instanceof
chain is not generally considered good OO practice. Rather than passing around bare lists and then trying to guess their constituent types consider creating a wrapper class for the lists which may also hold a reference to a Class
object. That way you may also be able to refactor your different processing algorithms as overriding a single process()
method...
来源:https://stackoverflow.com/questions/8145642/finding-the-specific-type-held-in-an-arraylistobject-ie-object-string-etc