core/src/com/google/inject/internal/InjectorImpl.java
private <T> BindingImpl<T> createJustInTimeBinding(
      Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType)
      throws ErrorsException {
    int numErrorsBefore = errors.size();

    // Retrieve the sources before checking for blacklisting to guard against sources becoming null
    // due to a full GC happening after calling state.isBlacklisted and
    // state.getSourcesForBlacklistedKey.
    // TODO(user): Consolidate these two APIs.
    Set<Object> sources = state.getSourcesForBlacklistedKey(key);
    if (state.isBlacklisted(key)) {
      throw errors.childBindingAlreadySet(key, sources).toException();
    }

    // Handle cases where T is a Provider<?>.
    if (isProvider(key)) {
      // These casts are safe. We know T extends Provider<X> and that given Key<Provider<X>>,
      // createProviderBinding() will return BindingImpl<Provider<X>>.
      @SuppressWarnings({"unchecked", "cast"})
      BindingImpl<T> binding = (BindingImpl<T>) createProviderBinding((Key) key, errors);
      return binding;
    }

    // Handle cases where T is a MembersInjector<?>
    if (isMembersInjector(key)) {
      // These casts are safe. T extends MembersInjector<X> and that given Key<MembersInjector<X>>,
      // createMembersInjectorBinding() will return BindingImpl<MembersInjector<X>>.
      @SuppressWarnings({"unchecked", "cast"})
      BindingImpl<T> binding = (BindingImpl<T>) createMembersInjectorBinding((Key) key, errors);
      return binding;
    }

    // Try to convert a constant string binding to the requested type.
    BindingImpl<T> convertedBinding = convertConstantStringBinding(key, errors);
    if (convertedBinding != null) {
      return convertedBinding;
    }

    if (!isTypeLiteral(key) && jitDisabled && jitType != JitLimitation.NEW_OR_EXISTING_JIT) {
      throw errors.jitDisabled(key).toException();
    }

    // If the key has an annotation...
    if (key.getAnnotationType() != null) {
      // Look for a binding without annotation attributes or return null.
      if (key.hasAttributes() && !options.exactBindingAnnotationsRequired) {
        try {
          Errors ignored = new Errors();
          return getBindingOrThrow(key.withoutAttributes(), ignored, JitLimitation.NO_JIT);
        } catch (ErrorsException ignored) {
          // throw with a more appropriate message below
        }
      }
      throw errors.missingImplementationWithHint(key, this).toException();
    }

    Object source = key.getTypeLiteral().getRawType();
    BindingImpl<T> binding =
        createUninitializedBinding(key, Scoping.UNSCOPED, source, errors, true);
    errors.throwIfNewErrors(numErrorsBefore);
    initializeJitBinding(binding, errors);
    return binding;
  }
private <T> BindingImpl<T> createJustInTimeBinding(
      Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType)
      throws ErrorsException {
    int numErrorsBefore = errors.size();

    // Retrieve the sources before checking for blacklisting to guard against sources becoming null
    // due to a full GC happening after calling state.isBlacklisted and
    // state.getSourcesForBlacklistedKey.
    // TODO(user): Consolidate these two APIs.
    Set<Object> sources = state.getSourcesForBlacklistedKey(key);
    if (state.isBlacklisted(key)) {
      throw errors.childBindingAlreadySet(key, sources).toException();
    }

    // Handle cases where T is a Provider<?>.
    if (isProvider(key)) {
      // These casts are safe. We know T extends Provider<X> and that given Key<Provider<X>>,
      // createProviderBinding() will return BindingImpl<Provider<X>>.
      @SuppressWarnings({"unchecked", "cast"})
      BindingImpl<T> binding = (BindingImpl<T>) createProviderBinding((Key) key, errors);
      return binding;
    }

    // Handle cases where T is a MembersInjector<?>
    if (isMembersInjector(key)) {
      // These casts are safe. T extends MembersInjector<X> and that given Key<MembersInjector<X>>,
      // createMembersInjectorBinding() will return BindingImpl<MembersInjector<X>>.
      @SuppressWarnings({"unchecked", "cast"})
      BindingImpl<T> binding = (BindingImpl<T>) createMembersInjectorBinding((Key) key, errors);
      return binding;
    }

    // Try to convert a constant string binding to the requested type.
    BindingImpl<T> convertedBinding = convertConstantStringBinding(key, errors);
    if (convertedBinding != null) {
      return convertedBinding;
    }

    if (!isTypeLiteral(key) && jitDisabled && jitType != JitLimitation.NEW_OR_EXISTING_JIT) {
      throw errors.jitDisabled(key).toException();
    }

    // If the key has an annotation...
    if (key.getAnnotationType() != null) {
      // Look for a binding without annotation attributes or return null.
      if (key.hasAttributes() && !options.exactBindingAnnotationsRequired) {
        try {
          Errors ignored = new Errors();
          return getBindingOrThrow(key.withoutAttributes(), ignored, JitLimitation.NO_JIT);
        } catch (ErrorsException ignored) {
          // throw with a more appropriate message below
        }
      }
      throw errors.missingImplementationWithHint(key, this).toException();
    }

    Object source = key.getTypeLiteral().getRawType();
    BindingImpl<T> binding =
        createUninitializedBinding(key, Scoping.UNSCOPED, source, errors, true);
    errors.throwIfNewErrors(numErrorsBefore);
    initializeJitBinding(binding, errors);
    return binding;
  }
private < T > BindingImpl < T > createJustInTimeBinding ( Key < T > key , Errors errors , boolean jitDisabled , JitLimitation jitType ) throws ErrorsException { int numErrorsBefore = errors . size ( ) ; // Retrieve the sources before checking for blacklisting to guard against sources becoming null // due to a full GC happening after calling state.isBlacklisted and // state.getSourcesForBlacklistedKey. // TODO(user): Consolidate these two APIs. Set < Object > sources = state . getSourcesForBlacklistedKey ( key ) ; if ( state . isBlacklisted ( key ) ) { throw errors . childBindingAlreadySet ( key , sources ) . toException ( ) ; } // Handle cases where T is a Provider<?>. if ( isProvider ( key ) ) { // These casts are safe. We know T extends Provider<X> and that given Key<Provider<X>>, // createProviderBinding() will return BindingImpl<Provider<X>>. @ SuppressWarnings ( { "unchecked" , "cast" } ) BindingImpl < T > binding = ( BindingImpl < T > ) createProviderBinding ( ( Key ) key , errors ) ; return binding ; } // Handle cases where T is a MembersInjector<?> if ( isMembersInjector ( key ) ) { // These casts are safe. T extends MembersInjector<X> and that given Key<MembersInjector<X>>, // createMembersInjectorBinding() will return BindingImpl<MembersInjector<X>>. @ SuppressWarnings ( { "unchecked" , "cast" } ) BindingImpl < T > binding = ( BindingImpl < T > ) createMembersInjectorBinding ( ( Key ) key , errors ) ; return binding ; } // Try to convert a constant string binding to the requested type. BindingImpl < T > convertedBinding = convertConstantStringBinding ( key , errors ) ; if ( convertedBinding != null ) { return convertedBinding ; } if ( ! isTypeLiteral ( key ) && jitDisabled && jitType != JitLimitation . NEW_OR_EXISTING_JIT ) { throw errors . jitDisabled ( key ) . toException ( ) ; } // If the key has an annotation... if ( key . getAnnotationType ( ) != null ) { // Look for a binding without annotation attributes or return null. if ( key . hasAttributes ( ) && ! options . exactBindingAnnotationsRequired ) { try { Errors ignored = new Errors ( ) ; return getBindingOrThrow ( key . withoutAttributes ( ) , ignored , JitLimitation . NO_JIT ) ; } catch ( ErrorsException ignored ) { // throw with a more appropriate message below } } throw errors . missingImplementationWithHint ( key , this ) . toException ( ) ; } Object source = key . getTypeLiteral ( ) . getRawType ( ) ; BindingImpl < T > binding = createUninitializedBinding ( key , Scoping . UNSCOPED , source , errors , true ) ; errors . throwIfNewErrors ( numErrorsBefore ) ; initializeJitBinding ( binding , errors ) ; return binding ; }
Returns a new just-in-time binding created by resolving {@code key}. The strategies used to
create just-in-time bindings are:

<ol>
<li>Internalizing Providers. If the requested binding is for {@code Provider<T>}, we delegate
to the binding for {@code T}.
<li>Converting constants.
<li>ImplementedBy and ProvidedBy annotations. Only for unannotated keys.
<li>The constructor of the raw type. Only for unannotated keys.
</ol>

@throws com.google.inject.internal.ErrorsException if the binding cannot be created.
Returns a new just - in - time binding created by resolving { @code key } . The strategies used to create just - in - time bindings are :