Details
-
Type:
Bug Detection
-
Status: Active
-
Resolution: Unresolved
-
Message:Use constructor injection for this field.
-
Default Severity:Major
-
Impact:Low
-
Likelihood:High
-
Covered Languages:Java
-
Remediation Function:Constant/Issue
-
Constant Cost:5min
-
Analysis Scope:Main Sources, Test Sources
Description
Field injection seems like a tidy way to get your classes what they need to do their jobs, but it's really a NullPointerException waiting to happen unless all your class constructors are private. That's because any class instances that are constructed by callers, rather than instantiated by a Dependency Injection framework compliant with the JSR-330 (Spring, Guice, ...), won't have the ability to perform the field injection.
Instead @Inject should be moved to the constructor and the fields required as constructor parameters.
This rule raises an issue when classes with non-private constructors (including the default constructor) use field injection.
Noncompliant Code Example
class MyComponent { // Anyone can call the default constructor @Inject MyCollaborator collaborator; // Noncompliant public void myBusinessMethod() { collaborator.doSomething(); // this will fail in classes new-ed by a caller } }
Compliant Solution
class MyComponent { private final MyCollaborator collaborator; @Inject public MyComponent(MyCollaborator collaborator) { Assert.notNull(collaborator, "MyCollaborator must not be null!"); this.collaborator = collaborator; } public void myBusinessMethod() { collaborator.doSomething(); } }
Attachments
Issue Links
- is implemented by
-
SONARJAVA-1275 Rule S3306: Constructor injection should be used instead of field injection
-
- Closed
-