@ SuppressWarnings ( "rawtypes" ) private static < T > Constructor < T > findConstructor ( final Class < T > clazz , final Object ... args ) throws NoSuchConstructorException , AmbiguousConstructorException { final Object [ ] cArgs = ( args == null ) ? new Object [ 0 ] : args ; Constructor < T > constructorToUse = null ; final Constructor < ? > [ ] candidates = clazz . getConstructors ( ) ; Arrays . sort ( candidates , ConstructorComparator . INSTANCE ) ; int minTypeDiffWeight = Integer . MAX_VALUE ; Set < Constructor < ? > > ambiguousConstructors = null ; for ( final Constructor candidate : candidates ) { final Class [ ] paramTypes = candidate . getParameterTypes ( ) ; if ( constructorToUse != null && cArgs . length > paramTypes . length ) { // Already found greedy constructor that can be satisfied. // Do not look any further, there are only less greedy // constructors left. break ; } if ( paramTypes . length != cArgs . length ) { continue ; } final int typeDiffWeight = getTypeDifferenceWeight ( paramTypes , cArgs ) ; if ( typeDiffWeight < minTypeDiffWeight ) { // Choose this constructor if it represents the closest match. constructorToUse = candidate ; minTypeDiffWeight = typeDiffWeight ; ambiguousConstructors = null ; } else if ( constructorToUse != null && typeDiffWeight == minTypeDiffWeight ) { if ( ambiguousConstructors == null ) { ambiguousConstructors = new LinkedHashSet < Constructor < ? > > ( ) ; ambiguousConstructors . add ( constructorToUse ) ; } ambiguousConstructors . add ( candidate ) ; } } if ( ambiguousConstructors != null && ! ambiguousConstructors . isEmpty ( ) ) { throw new AmbiguousConstructorException ( clazz , cArgs , ambiguousConstructors ) ; } if ( constructorToUse == null ) { throw new NoSuchConstructorException ( clazz , cArgs ) ; } return constructorToUse ; }
Find a Constructor on the given type that matches the given arguments .