在Java语言中初次使用自定义类的数组时,参照C++中的自定义类数组,编写了如下代码

    1. public class Test {
    2. public static void main(String[] args) {
    3. Person[] persons = new Person[3];
    4. persons[0].name = "Rookiegan";
    5. persons[0].age = 22;
    6. for(Person p : persons) {
    7. System.out.println("name:" + p.name);
    8. System.out.println("age: " + p.age);
    9. }
    10. }
    11. static class Person {
    12. String name;
    13. int age;
    14. }
    15. }

    从C++的逻辑来看,这段代码似乎没有问题,编译也顺利通过,但在执行的时候在persons[0].name = “Rookiegan”;这一句抛出空指针异常,也就是说persons[0]根本没有指向一段真正的内存空间。于是我为Person类添加了自定义的构造函数,输出打印信息。

    1. Person() {
    2. System.out.println("Person Constructor");
    3. }

    测试发现现象与不加一样,这个构造函数根本没有执行。

    查阅资料发现,由于Java中引用变量存储在栈中,而真正的对象存储在堆中,Person[] persons = new Person[3];这个语句根本不会为数组的成员分配内存,只是在栈中定义一个Person[]类的引用,该引用会执向3个Person类的对象。

    将程序进行如下更改,编译通过,且执行正常。

    1. public class Test {
    2. public static void main(String[] args) {
    3. Person[] persons = new Person[3];
    4. // 如不使用用以下三行代码,执行到persons[0].name = "Rookiegan"时会报空指针异常
    5. persons[0] = new Person();
    6. persons[1] = new Person();
    7. persons[2] = new Person();
    8. persons[0].name = "Rookiegan";
    9. persons[0].age = 22;
    10. for(Person p : persons) {
    11. System.out.println("name:" + p.name);
    12. System.out.println("age: " + p.age);
    13. }
    14. }
    15. static class Person {
    16. String name;
    17. int age;
    18. Person() {
    19. System.out.println("Person Constructor");
    20. }
    21. }
    22. }