Repository: apache/dubbo
File: dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/api/pu/AbstractPortUnificationServer.java (Java)

Code before:
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;

public abstract class AbstractPortUnificationServer extends AbstractServer {

    /**
     * extension name -> activate WireProtocol
     */
    private volatile Map<String, WireProtocol> protocols;

    /*
    protocol name --> URL object
    wire protocol will get url object to config server pipeline for channel
     */
    private Map<String, URL> supportedUrls = new ConcurrentHashMap<>();

    /*
    protocol name --> ChannelHandler object
    wire protocol will get handler to config server pipeline for channel
    (for triple protocol, it's a default handler that do nothing)
     */
    private Map<String, ChannelHandler> supportedHandlers = new ConcurrentHashMap<>();

    public AbstractPortUnificationServer(URL url, ChannelHandler handler) throws RemotingException {
        super(url, handler);
    }

    public Map<String, WireProtocol> getProtocols() {
        return protocols;
    }

    @Override
    protected final void doOpen() {
        // initialize supportedUrls and supportedHandlers before potential usage to avoid NPE.
        supportedUrls = new ConcurrentHashMap<>();
        supportedHandlers = new ConcurrentHashMap<>();

        ExtensionLoader<WireProtocol> loader =
                getUrl().getOrDefaultFrameworkModel().getExtensionLoader(WireProtocol.class);
        Map<String, WireProtocol> protocols = loader.getActivateExtension(getUrl(), new String[0]).stream()
                .collect(Collectors.toConcurrentMap(loader::getExtensionName, Function.identity()));
        // load extra protocols
        String extraProtocols = getUrl().getParameter(EXT_PROTOCOL);
        if (StringUtils.isNotEmpty(extraProtocols)) {
            Arrays.stream(extraProtocols.split(COMMA_SEPARATOR)).forEach(p -> {
                protocols.put(p, loader.getExtension(p));
            });

Review comment (suggestion):
The field is initialized at declaration and then re-initialized in doOpen(). This creates unnecessary object creation. Either remove the declaration initialization or the doOpen() initialization.

Code after:
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;

public abstract class AbstractPortUnificationServer extends AbstractServer {

    /**
     * extension name -> activate WireProtocol
     */
    private volatile Map<String, WireProtocol> protocols;

    /*
    protocol name --> URL object
    wire protocol will get url object to config server pipeline for channel
     */
    private Map<String, URL> supportedUrls;

    /*
    protocol name --> ChannelHandler object
    wire protocol will get handler to config server pipeline for channel
    (for triple protocol, it's a default handler that do nothing)
     */
    private Map<String, ChannelHandler> supportedHandlers;

    public AbstractPortUnificationServer(URL url, ChannelHandler handler) throws RemotingException {
        super(url, handler);
    }

    public Map<String, WireProtocol> getProtocols() {
        return protocols;
    }

    @Override
    protected final void doOpen() {
        // initialize supportedUrls and supportedHandlers before potential usage to avoid NPE.
        supportedUrls = new ConcurrentHashMap<>();
        supportedHandlers = new ConcurrentHashMap<>();

        ExtensionLoader<WireProtocol> loader =
                getUrl().getOrDefaultFrameworkModel().getExtensionLoader(WireProtocol.class);
        Map<String, WireProtocol> protocols = loader.getActivateExtension(getUrl(), new String[0]).stream()
                .collect(Collectors.toConcurrentMap(loader::getExtensionName, Function.identity()));
        // load extra protocols
        String extraProtocols = getUrl().getParameter(EXT_PROTOCOL);
        if (StringUtils.isNotEmpty(extraProtocols)) {
            Arrays.stream(extraProtocols.split(COMMA_SEPARATOR)).forEach(p -> {
                protocols.put(p, loader.getExtension(p));
            });