Java自定义类创建对象数组并赋值

一、起因

    采用下面的代码为对象数组里面的每个元素的字段赋值时报错。

public class StudentArray {
    public static void main(String[] args){
        Student[] stuArr = new Student[5]; //创建对象数组,stuArr存储地址

        for(int i = 0; i < stuArr.length; ++i){
            System.out.println(stuArr[i]); //null

            stuArr[i].number = i + 1; //报错
            stuArr[i].state = (int)Math.round(Math.random() * 3);
            stuArr[i].score = (int)Math.round(Math.random() * 100);
            System.out.println(stuArr[i]);
        }
    }
}

class Student{
    int number;
    int state;
    int score;

    @Override
    public String toString() {
        return "Student{" +
                "number=" + number +
                ", state=" + state +
                ", score=" + score +
                '}';
    }
}

    错误信息如下:自定义对象数组的元素的值为null,报空指针异常。

null
Exception in thread "main" java.lang.NullPointerException: Cannot assign field "number" because "stuArr[i]" is null
	at com.zhangqu.java.method.StudentArray.main(StudentArray.java:19)

    原因分析:因为Student[] stuArr = new Student[5];创建对象数组时,返回系统为该对象数组在堆区分配的空间的地址,并将地址值存储到引用变量stuArrstuArr的数据类型为类数组Student[],是引用类型;而该数组的每一个元素都是类Student的对象(本质是引用,存储null或地址值),数组的每一个元素的数据类型为类Student,也是引用类型,由于没有继续使用new为这些引用类型Student类对象分配空间,所有数组的元素默认被初始化为null在这里插入图片描述

    不较真的情况下,可以把Student[] stuArr = new Student[5];看做如下形式:

Student stu1 = null;
Student stu2 = null;
......
Student stu5 = null;
Student[] stuArr = {stu1, stu2, ..., stu5}

二、正确代码

public class StudentArray {
    public static void main(String[] args){
        Student[] stuArr = new Student[5]; //创建对象数组,stuArr存储地址, 初始化变量stuArr
        int num = 0;
        for (Student stu : stuArr) {
            System.out.println(stu); //null

            stu = new Student(); //用new分配空间,显式的为数组的每一个元素赋值,stu存储地址
            System.out.println(stu);
            System.out.println(stu.getClass().toString()); //获取数据类型

            stu.number = ++num;
            stu.state = (int)Math.round(Math.random() * 3);
            stu.score = (int)Math.round(Math.random() * 100);
            System.out.println(stu);
        }
    }
}

class Student{
    int number;
    int state;
    int score;

    @Override
    public String toString() {
        return "Student{" +
                "number=" + number +
                ", state=" + state +
                ", score=" + score +
                '}';
    }
}

运行结果:

null
Student{number=0, state=0, score=0}
class com.zhangqu.java.method.Student
Student{number=1, state=1, score=10}
null
Student{number=0, state=0, score=0}
class com.zhangqu.java.method.Student
Student{number=2, state=0, score=42}
......

    内存分析概要图如下:
正确创建对象数组
    由于是自定义的类,所以创建对象数组时,第一步是用new为数组对象本身分配空间(初始化),第二步是用new为数组对象的元素分配空间(赋值)。

public class StudentArray {
    public static void main(String[] args){
    }

    @Test
    void testObjArr(){
        StuObjArr[] stuObjArrs = new StuObjArr[2]; //第一步,为对象数组分配空间,初始化stuObjArrs
        for(int i = 0; i < stuObjArrs.length; i++){
            stuObjArrs[i] = new StuObjArr(); //第二步,为数组元素分配空间,为stuObjArrs[i]赋值
            System.out.println(stuObjArrs[i]); //打印数组元素在堆区的地址
        }
    }
}

class StuObjArr{
    int id;
    String name;
}

运行结果:

com.zhangqu.java.method.StuObjArr@2a70a3d8
com.zhangqu.java.method.StuObjArr@289d1c02

最后附上一张数据类型图,基础真的很重要。
引用类型的变量,只能存储两类值,null或地址值(含变量的数据类型)
Java数据类型

  • 20
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值