types - Groovy coercing List to Map doesn't throw ClassCastException or what is ArrayList1_groovyProxy? -
i writing code tried cast object map.
map = object map
i alternatively use
map = (map) object
and whole question irrelevant throws classcastexception
if object of type list, using former encountered interesting thing. if object list, i.e. object = []
, groovy type coercion behave different expected.
my expectation classcastexception
, instead got resulting object. object seems odd. instance of list , instance of map , using .tostring()
on resulted in output of list, not map ([a,b]
). not possible set value on map a['c'] = 'c'
. results in java.lang.illegalargumentexception: argument type mismatch
.
map = ['a', 'b'] map println(a) println(a instanceof list) println(a instanceof map) println(a.getclass())
results in following output:
[a, b] true true class arraylist1_groovyproxy
i tried google find out arraylist1_groovyproxy
is, couldn't find anything.
it still doesn't make sense me, coercion returns object not should , seems kind of broken, instead of throwing classcastexception
.
can explain me reasoning behind behavior instead of throwing exception , explain use of arraylist1_groovyproxy
? or bug in groovy?
the as
operator calls astype
method provided type argument method.
you can see default implementation astype
in defaultgroovymethods
.
since map
interface, call proxygenerator.instance.instantiatedelegate(interfaces, obj)
, returns dynamic proxy implements map
.
/** * converts given object type. method used through * "as" operator , overloadable other operator. * * @param obj object convert * @param type goal type * @return resulting object * @since 1.0 */ @suppresswarnings("unchecked") public static <t> t astype(object obj, class<t> type) { if (string.class == type) { return (t) invokerhelper.tostring(obj); } // fall cast try { return (t) defaulttypetransformation.casttotype(obj, type); } catch (groovycastexception e) { metaclass mc = invokerhelper.getmetaclass(obj); if (mc instanceof expandometaclass) { expandometaclass emc = (expandometaclass) mc; object mixedin = emc.casttomixedtype(obj, type); if (mixedin != null) return (t) mixedin; } if (type.isinterface()) { try { list<class> interfaces = new arraylist<class>(); interfaces.add(type); return (t) proxygenerator.instance.instantiatedelegate(interfaces, obj); } catch (groovyruntimeexception cause) { // ignore } } throw e; }
as why groovy goes such great lengths coerce types--it's nature of groovy: making java coding easier. can construct object passing map
constructor, or coerce map
instance particular type; why not let every object coerced map
via as
operator?
Comments
Post a Comment