有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

是否有必要在构造函数中指定每个Java类属性?

这听起来可能很傻,但我想知道,当我们在类中声明一个类属性时,该类属性必须在构造函数中,还是我们只在想要初始化它时才把它放在构造函数中

例如,我可以这样做吗

Public class A {
    private int n;
    private string name;
    
    public A(int n) { 
        this.n = n;
    }
}

注意,我没有在构造函数中放入类属性“name”,这会导致系统抛出异常吗?如果是这样,如果我在类A下创建的以下方法之一中使用“name”,它会抛出NoPointerException吗


共 (2) 个答案

  1. # 1 楼答案

    关于不给构造函数中的字段赋值:是的,您可以这样做,但通常应该尝试避免null,尤其是,如果具有null值的字段会使对象实例处于无效或未定义的状态

    如果您只是使用“getter”返回字段:getName(): String,那么它不会抛出NullPointerException:仅当您尝试使用name调用String方法时才会抛出。如果其中一个参数的计算结果为^{,那么您调用的方法也可能会抛出异常

    如果您决定返回name,而它可能仍然是null,那么您可能应该返回一个Optional<String>

    如果标记字段final,则确实需要分配它,但这也意味着此后不能更改引用。如果你想强制分配,你可以annotate using ^{} or similar

  2. # 2 楼答案

    构造函数不必显式初始化每个属性。如上所述,将使用默认值。在构造函数中选择要做什么是一种设计选择

    通过使所有属性成为构造函数的参数,可以强制它们具有良好的初始值。这样做的好处是,您无法创建“坏”对象。它的缺点是构造函数需要为每个属性提供参数,这使得添加新属性变得困难

    对于未明确给出的属性,构造函数可以接受Java默认值,或者构造函数可以将属性设置为自己的默认值

    也可以有多个具有不同参数的构造函数

    在某些情况下,必须包含无参数构造函数。当使用某些期望类的行为类似于JavaBean的框架时,这是正确的。如果这没什么意义,现在就别担心了

    所以你可以定义你的类,如下所示。显然,您会想要定义更多的方法,比如getter和setter,但是为了简单起见,没有显示这些方法

    public class A
    {
        private int n;
    
        private String name;
        
        public A ()
        {
            n = 42;
            name = "na";
        }
    
        public A (int n)
        {
            this.n = n;
            // name will be null
        }
    
        public A (int n, String name)
        {
            this.n = n;
            this.name = name;
        }
    }