繁体   English   中英

当我尝试向数组添加值时出现java.lang.NullPointerException

[英]java.lang.NullPointerException when I try to add value to Array

我有一个任务来制作自己的动态数组,而无需在Java中使用任何ArrayListArrayList的其他预制类。 尝试添加对象时(例如,它是Integer), Exception in thread "main" java.lang.NullPointerException收到Exception in thread "main" java.lang.NullPointerException

Dinaminis<Integer> array = new Dinaminis<>();
array.ideti(5);

我的Dinaminis课程看起来像这样:

public class Dinaminis<T> implements DArray<T> 
{    
    private Object[] array;
    private int kiek;
    private Object[] temp;

    public Dinaminis() {
        array = new Object[10];
        kiek = 0;
    }

    @Override
    public void ideti(Object o) {
        if (array.length == kiek) {
            temp = new Object[kiek*2];
        }
        for (int i=1; i < kiek; i++){
            temp[i] = array[i];
        }
        array = temp;
        array[kiek] = o;
        kiek++;
    }
}

问题是,当我想使用“ ideti”方法时,我想检查数组是否已满,如果数组已满,则应创建一个双倍大小的数组。 但是,即使在我的阵列已满之前,我也会收到错误消息。

您的ideti方法错误。 这应该工作:

public void ideti(Object o) {
    if (array.length == kiek) {
        temp = new Object[kiek*2];
        // only copy old array to new array when old one is full
        for (int i=0; i < kiek; i++){ // index starts at 0, not 1
            temp[i] = array[i];
        }
        array = temp;
    } 
    array[kiek] = o;
    kiek++;
}

您的问题是,即使原始数组未满,也执行了将旧数组复制到新数组的循环,在这种情况下temp没有初始化,这导致NullPointerException

我建议您将array存储为通用类型T 我将把Class<T>传递给Dinaminis构造函数,然后可以使用Array.newInstance() 另外,我更喜欢使用System.arraycopy()并覆盖toString()例如

public class Dinaminis<T> implements DArray<T> {
    private T[] array;
    private int kiek;
    private Class<T> cls;

    public Dinaminis(Class<T> cls) {
        this.cls = cls;
        array = (T[]) Array.newInstance(cls, 10);
        kiek = 0;
    }

    @Override
    public void ideti(T o) {
        if (kiek == array.length) {
            T[] temp = (T[]) Array.newInstance(cls, array.length * 2);
            System.arraycopy(array, 0, temp, 0, array.length);
            array = temp;
        }
        array[kiek++] = o;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("len = %d [", array.length));
        for (int i = 0; i < kiek; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append(array[i]);
        }
        sb.append("]");
        return sb.toString();
    }
}

然后你可以用类似的东西进行测试

public static void main(String[] args) {
    DArray<Integer> t = new Dinaminis<Integer>(Integer.class);
    for (int i = 0; i < 11; i++) {
        t.ideti(i);
    }
    System.out.println(t);
}

输出是

len = 20 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

显然,出于教学原因, len被添加到了此输出中,在实际代码中,我可能不会显示它(也许在日志消息中除外)。

您需要先初始化您的临时数组,然后再使用它。

您可以在if中初始化它,但不能在if之外初始化它

temp = new Object [kiek * 2];

因此,双精度数组的分配仅应在数组大小完成时进行

if (array.length == kiek)  //check if array size is reached
{ 

  temp = new Object[kiek*2]; //allocate a double sized array

  for (int i=1; i < kiek; i++) //copy elements - are you sure you don't want to start with i=0? You won't copy the first element if you start at 1
  {
    temp[i] = array[i];
  }
  array = temp;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM