私有构造函数是否是默认构造函数?

时间:2016-05-25 15:45:39

标签: java

根据Java Spec,默认构造函数是一个带有no-args的构造函数,如果你没有定义它,则由编译器提供:

Java语言规范

  

8.8.9。默认构造函数

     

如果类不包含构造函数声明,则隐式声明默认构造函数。顶级>的默认构造函数的形式class,member class或local class如下:

     

默认构造函数与类具有相同的可访问性(第6.6节)。

     

默认构造函数没有形式参数,除非在非私有内部成员类中,默认构造函数隐式声明一个形式参数,表示该类的直接封闭实例(§8.8.1,§15.9.2,§) 15.9.3)。

     

默认构造函数没有throws子句。

     

如果声明的类是原始类Object,则默认构造函数具有空体。否则,默认构造函数只调用不带参数的超类构造函数。

我一直认为它还需要一个公共构造函数,但今天,当我使用一些JAXB映射时,我决定提取一个静态的create方法,然后IDE已自动将我的构造函数转换为私有构造函数。

被修改

所以我意识到我不再需要no-args构造函数,然后将其删除。所以JAXB停止工作记录以下消息:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
org.yourproject.YourClass does not have a no-arg default constructor.

JAXB可以使用私有的无参数构造函数,但是当我删除它时,会记录上面的错误消息,要求输出 no-args默认构造函数

我的问题是: private no-args构造函数是否也可以称为默认构造函数

这是我的JAXB映射(省略了getter和setter):

@XmlRootElement(name = "getagentstatus")
public class EccpGetAgentStatusRequest extends EccpAbstractRequest {

    public static EccpGetAgentStatusRequest create(String agentNumber) {
        return new EccpGetAgentStatusRequest(agentNumber);
    }

    @XmlElement(name = "agent_number")
    private String agentNumber;

    private EccpGetAgentStatusRequest() {
    }

    private EccpGetAgentStatusRequest(String agentNumber) {
        this.agentNumber = agentNumber;
    }
}

请求包装器:

@XmlRootElement(name = "request")
public class EccpRequestWrapper {

    @XmlAttribute
    private Long id;

    @XmlAnyElement
    private IEccpRequest request;

    public void setRequest(IEccpRequest request) {
        this.id = request.getId();
        this.request = request;
    }
}

这是我的测试代码:

public class Test {

    public static void main(String... args) {
        try {
            EccpGetAgentStatusRequest wrapped = EccpGetAgentStatusRequest.create("Agent/1000");
            EccpRequestWrapper requestWrapper = new EccpRequestWrapper();
            requestWrapper.setRequest(wrapped);
            JAXBContext jc = JAXBContext.newInstance(EccpRequestWrapper.class, wrapped.getClass());
            Marshaller marshaller = jc.createMarshaller();
            marshaller.marshal(requestWrapper, System.out);
        } catch (JAXBException ex) {
            ex.printStackTrace();
        }
    }

}

1 个答案:

答案 0 :(得分:2)

JAXB需要一个no-args构造函数,它可以使用反射调用来创建对象。 JAXB并不关心构造函数的访问权限,因为它将可访问性设置为true。因此,如果您没有提供构造函数,那么JAXB就可以了,因为您的类被赋予了默认构造函数。如果您编写自己的私有无参数构造函数,那么JAXB也可以。如果您提供自己的构造函数,该构造函数接受一个或多个参数,并且您没有提供无参数构造函数,则不会为该类创建默认构造函数,并且JAXB无法创建该类的对象。 / p>

术语方面,"默认构造函数"在引用的JLS段落中定义,仅适用于编译器提供的构造函数,当您不提供任何构造函数时。使用其他术语似乎不准确。