With Java reflection, one can get a constructor through getConstructor(klass, args).
However, when we pass as args a derived class of the class specified in the constructor signature, it fails. How to overcome this issue?
For example,
HashSet.class.getConstructor(new Class[]{ HashSet.class });
fails. While
HashSet.class.getConstructor(new Class[]{ Collection.class });
succeeds.
I am looking for something that could easily be used in clojure. Therefore, I would prefer to have something out of the box and not having to add user-defined functions.
Any idea, how to solve this issue?
Building on the answers of esaj and T.J. Crowder:
The following returns a seq of constructors for the given class which are (1) callable with the specified argument types and (2) optimal in the sense that their declared parameter types are removed by a minimal number of steps up the inheritance ladder from the specified argument types. (Thus an exact match will always be returned alone; if there are two constructors which require casting from some of the specified argument types to their grandparent types, and there is no closer match, they will both be returned; if there are no matching constructors at all,
nilwill be returned.) Primitive argument types may be specified as symbols or keywords (i.e.'int/:int). Finally, primitive types are considered equivalent to their boxed counterparts.Example:
One might want to permit widening numeric conversions; that could be done e.g. by adding
Integer->Longetc. mappings toconvmand tweaking theifcondition incount-stepsbelow.Here’s the code: