Inject into private, package or public field or provide a setter?

Viewed 14306

I see many Java examples using dependency injection with private fields without a public setter like this:

public SomeClass {
  @Inject
  private SomeResource resource;
}

But that is a bad idea when the injection should be performed manually for example in unit tests.

There are several possibilities to solve this:

  • add a public setter: setSomeResource(SomeResource r)
  • make the field public
  • make the field package protected

I'd like to avoid the setter, since nothing really happens in it. So I'd prefer public or package protected. What do you recommend?

7 Answers

One way to avoid creating a setter for the field is using constructor injection. This even allows you to declare the field as final.

It goes like this:

public class SomeClass {
    private final SomeResource resource;

    @Inject
    public SomeClass(SomeResource resource) {
        this.resource = resource;
    }
}

Adding setters is not an optimal solution, since you are adding production code which is not needed.

An alternative is to use Spring's ReflectionTestUtils class to inject your test dependencies using reflection, see http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/test/util/ReflectionTestUtils.html

EDIT (2017): However, reflection is an even worse solution than adding setters. The cause of this mess is the fact that Spring makes it possible to inject values without setters or constructors. My current stance is to stick to using either of those and avoid using black magic injection practices.

I prefer the setter

  • it is easier to debug (put a breakpoint in a setter rather than on field access / modification)
  • easier to log
  • easier to add some validation (although this is not always the best place)
  • easier to support bidirectional maintainance (though IOC container can take care of that)
  • any other "manual AOP" purpose

But that's just my opinion

I recommend using setter. In this question are the benefits of using getters and setters.

Related