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;
  }
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.