Skip to content

[Feature] Avoid Calling Other Methods in Constructors #15600

@zrlw

Description

@zrlw

Pre-check

  • I am sure that all the content I provide is in English.

Search before asking

  • I had searched in the issues and found no similar feature requirement.

Apache Dubbo Component

Java SDK (apache/dubbo)

Descriptions

Key Reasons to Avoid Child Method Calls in Constructors

  1. ‌Incomplete Object Initialization‌: When a constructor calls other methods, those methods might execute before the object is fully initialized, leading to potential NullPointerExceptions or inconsistent states.
  2. Inheritance Issues‌: If the called method is overridden by a subclass, the subclass version will execute before the subclass constructor completes, violating the expected initialization order.
  3. Reduced Code Clarity‌: Constructors should focus solely on initialization. Adding method calls makes the code harder to understand and maintain.
  4. Testing Difficulties‌: Methods called during construction make unit testing more complex, as you can't test the constructor independently from those methods.

Better Alternatives
Instead of calling methods in constructors:

  • Initialize fields directly
  • Use factory methods
  • Implement lazy initialization
  • Apply the Initialization-on-demand holder idiom for singletons

Example of Problematic Code

public abstract class AAA {
	public AAA() {
                System.out.println("Build AAA");
		initialize();
	}

        protected void initialize();
}

public class BBB extends AAA {
	private final FFF myFinal = new FFF();
	
	public BBB() {
		super();
                System.out.println("Build BBB");
	}
	
        @Override
	public void initialize() {
                System.out.println("Run initialize");
		new Thread(() -> {
			// The assertion might fail because myFinal isn't initialized during running BBB construction.
			Assertions.assertNotNull(myFinal);
		}).start();
	}
}

public class FFF {
	public FFF() {
		System.out.println("Build FFF");
	}
}

Help Wanted
Keeping constructors simple and focused on field initialization to create more maintainable and reliable code that properly follows object-oriented principles.

Related issues

During the initialization process of AbstractServer, the doOpen() method publishes the uninitialized internal state to the external thread, resulting in: "this.dubboChannels" is null

Are you willing to submit a pull request to fix on your own?

  • Yes I am willing to submit a pull request on my own!

Code of Conduct

Metadata

Metadata

Labels

help wantedEverything needs help from contributorstype/bugBugs to being fixed

Type

No type

Projects

Status

Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions