Static members in an injected world

Dependency injection lets you write objects in such a way that you really don't have to care about how to construct your dependencies.  The mechanism can vary from framework to framework but it's usually as simple as putting @Inject or @Autowired on your field or perhaps your constructor paramaters and let the framework find those implementations for you.  I don't want to go into all the how tos of that here but you typically just have to write the construction code once for you dependencies in, say, a Guice module and then just inject away.  So now that we can easily get dependencies injected, the question arises, "What can/should we inject?"  My answer is, "everything." 

The beauty of injection is that you can swap out those dependency implementations based on your runtime environment.  As long as there's a common API to code to, the code accepting those injections need never know the difference.  When converting a large codebase from a traditional "new everything" approach to use guice, I started noticing we were using static methods on utility classes quite a lot.  Given how cheap injection is, I started converting those usages to injections and making those methods not static.  For me, this made things much "cleaner."  It was also, apparently, quite the controversial decision.

There is a school of thought that goes something like this:  "If there's no state on an object, don't inject it.  Make it static and just call those methods statically."  This is "wrong" for a number of reasons.  The biggest reason, to my mind, is that it conflates dependency  injection with state  injection.  The idea, it seems, is that if there's no state on the object, you should save yourself the expense of creating an object just to call its methods.  For me, though, the cost of instantiation is pretty low and these dependencies can be marked as singleton and only created once.  Once created, these objects can then be injected a million times with no extra overhead.

But bigger than that, is the second reason this school of thought is wrong:  I can change the actual object that gets injected whenever I like.  For example, say you have a set of utility methods that are environment aware:  developer's laptop, jenkins, staging, production, Customer A, Customer B, etc.  They send emails or initialize the database by deleting everything.  Whatever.  By simply changing the injection configuration, I can change the implementation to suit the runtime environment without ever changing anything but that configuration.  With static methods, you're stuck with whatever implementation exists on whichever implementation is bound the compiler.  Maybe that's fine for now but it locks your application in those choices in ways that aren't necessarily easy to change.

The decision to inject or not is largely stylistic, but I believe there are enough technical reasons to favor injection over statics and certainly there are more benefits to injection than statics.   Static members (methods in particular) are a code smell in normal circumstances that when we find cheap, easy ways to reduce them, I think we should take advantage of the opportunity.