当我在类的构造函数中声明并初始化它们时,为什么我的字段初始化为null或默认值为零?

时间:2017-02-08 15:38:09

标签: java constructor field

这是针对类似问题的规范性问题和答案,其中问题是阴影的结果。

我在我的类中定义了两个字段,一个是引用类型,另一个是基本类型。在类的构造函数中,我尝试将它们初始化为一些自定义值。

当我稍后查询这些字段的值时,它们会返回Java的默认值,null表示引用类型,0表示基本类型。为什么会这样?

这是一个可重复的例子:

public class Sample {
    public static void main(String[] args) throws Exception {
        StringArray array = new StringArray();
        System.out.println(array.getCapacity()); // prints 0
        System.out.println(array.getElements()); // prints null
    }
}

class StringArray {
    private String[] elements;
    private int capacity;
    public StringArray() {
        int capacity = 10;
        String[] elements;
        elements = new String[capacity];
    }
    public int getCapacity() {
        return capacity;
    }
    public String[] getElements() {
        return elements;
    }
}

我希望getCapacity()返回值10和getElements()以返回正确初始化的数组实例。

3 个答案:

答案 0 :(得分:2)

构造函数中的

int capacity = 10;声明了一个局部变量capacity shadow 该类的字段。

解决方法是放弃int

capacity = 10;

这将更改字段值。同上课中的其他领域。

你的IDE没有警告你这个阴影吗?

答案 1 :(得分:1)

另一个被广泛接受的约定是在类成员中添加一些前缀(或后缀 - 无论你喜欢什么),以区别于局部变量。

例如m_前缀为

的类成员
class StringArray {
  private String[] m_elements;
  private int      m_capacity;

  public StringArray(int capacity) {
    m_capacity = capacity;
    m_elements = new String[capacity];
  }

  public int getCapacity() {
    return m_capacity;
  }

  public String[] getElements() {
    return m_elements;
  }
}


大多数IDE已经支持这种表示法,下面是Eclipse

enter image description here

答案 2 :(得分:1)

在java / c / c ++中使用变量有两个部分。一种是声明变量,另一种是使用变量(无论是分配值还是在计算中使用它)。

声明变量时,必须声明其类型。所以你会用

istringstream

使用它时,您不必重新声明变量:

int x;   // to declare the variable
x = 7;   // to set its value

如果变量在同一范围内,则会出现编译错误;但是,正如您所发现的那样,如果变量在不同的范围内,您将掩盖第一个声明。