简体   繁体   English

Java中的空指针错误?

[英]Null-pointer error in Java?

I'm pretty new to this forum thing. 我对这个论坛话题还很陌生。 I'd always been pretty apprehensive about posting on forums but after two weeks of bashing my head against my code trying to make it work I'd finally given in. The code below is a critical part of some larger code but I think I've kind of pinpointed the problem section. 我一直都很担心在论坛上发帖,但是经过两周的反复抨击我的代码以使其正常工作,我终于给出了建议。下面的代码是一些较大代码的关键部分,但我认为ve指出了问题部分。 I have a 2D array of object which are supposed to be initialized by default as soon as it is created. 我有一个2D对象数组,应该在创建对象后默认情况下对其进行初始化。 This, however, does not seem to be happening and the value remains null. 但是,这似乎没有发生,并且该值保持为空。 Could this be the result of Java not being able to pass by reference? 这可能是Java无法通过引用传递的结果吗? If so then why is it that the primitive 2D arrays are instantiated perfectly fine? 如果是这样,为什么原始2D数组被完美实例化呢? Thank you in advance, Lasz. 预先感谢您,拉斯。

    class ObjectThing
    {
        int someInt;
        double someDouble;

        public ObjectThing()
        {
            someInt = 0;
            someDouble = 0;
        }

        synchronized private void someIntIncrement ()
        {
           someInt++;
        }

        synchronized public void addSomeDouble (double sd)
        {
            someDouble += sd;
            someIntIncrement ();
        }

        synchronized public String toString ()
        {
            return someInt + "," + someDouble;
        }
  }


  class AnotherObject
  {
          String name;
          ObjectThing [][] someObjectMAtrix;
          double [][] someDoubleMAtrix01;
          double [][] someDoubleMAtrix02;   

          public AnotherObject()
          {
          }

          private void initDouble (double [][] mat)
          {
             for (double [] i: mat)
                for (double j: i)
                   j = 0;
          }

          private void initObject (ObjectThing [][] so)
          {
              for (ObjectThing [] i: so)
                 for (ObjectThing j: i)
                    j = new ObjectThing ();
          }         

          public void init (int r, int c)
          {
              someObjectMAtrix =  new ObjectThing [r][c];
              someDoubleMAtrix01 = new double [r][c];
              someDoubleMAtrix01 = new double [r][c];         
          initObject (someObjectMAtrix);
              initDouble (someDoubleMAtrix01);
              initDouble (someDoubleMAtrix02);
          }
   }

   class Driver
   {
       public static void main (String [] args)
       {
            initializeMethod();
       }

       public void initializeMethod ()
       {
            AnotherObject [] anotherObjectArray = new AnotherObject [1];
            for (AnotherObject i: anotherObjectArray)
            {
                i.init(72,72);
            }
       }
   } 

The problem is in your initializeMethod: 问题出在您的initializeMethod中:

        AnotherObject [] anotherObjectArray = new AnotherObject [1];
        for (AnotherObject i: anotherObjectArray)
        {
            i.init(72,72);
        }

Going Object[] myArray = new Object[1] only allocates space for the array. 转到Object[] myArray = new Object[1]仅为数组分配空间。 It does not actually create these objects. 它实际上并没有创建这些对象。 Your code block should be 您的代码块应为

        AnotherObject [] anotherObjectArray = new AnotherObject [1];
        anotherObjectArray[0] = new AnotherObject();
        for (AnotherObject i: anotherObjectArray)
        {
            i.init(72,72);
        }

This is a bit clunky. 这有点笨拙。 I'm assuming you have some need for putting AnotherObject into arrays and you are just not showing it. 我假设您需要将AnotherObject放入数组中,而您只是不显示它。 If you only need one of those objects, then just create it directly. 如果只需要这些对象之一,则直接创建它。 You should probably have a look at Lists 您可能应该看看列表

I believe this is by design. 我相信这是设计使然。 A primitive will get allocated on the stack, and always have some sort of value by default. 一个原语将在堆栈上分配,并且默认情况下始终具有某种值。 An object gets allocated on the heap and will be passed around by reference. 对象在堆上分配,并将通过引用传递。 Those references will point to nothing by default until you initialize it. 在初始化之前,默认情况下,这些引用将不指向任何内容。

You just initialized the array of AnotherObject objects...but there is no AnotherObject in the first field of the array... It is null as you get it out, because you didn't initialize it. 您刚刚初始化了AnotherObject对象的数组...但是该数组的第一个字段中没有AnotherObject ...当您获取它时,它为null,因为您没有初始化它。 In the initializeMethod you have to do the following: 在initializeMethod中,您必须执行以下操作:

AnotherObject [] anotherObjectArray = new AnotherObject [1];
 for (AnotherObject i: anotherObjectArray)
    {
        i = new AnotherObject();
        i.init(72,72);
    }

cheers! 干杯!

The Java compiler will force you to initialise variables, primitives or reference types (like objects), or it will generate a compiler error and fail. Java编译器将迫使您初始化变量,原语或引用类型(如对象),否则将生成编译器错误并失败。

However, array initialisation will create an array of the desired size, with each element set to a default value. 但是,数组初始化将创建所需大小的数组,并将每个元素设置为默认值。 For primitives, this is something like 0 for numeric types, false for booleans. 对于基元,对于数字类型,这类似于0 ,对于布尔值,则为false For reference types , the default is null . 对于引用类型 ,默认值为null This is the source of your problem. 这是您问题的根源。

You correctly initialise the array, but do not populate it with valid values. 您正确初始化数组,但不要用有效值填充它。 So, it is not to do with pass-by-reference, but with proper array initialisation, and knowing the default values of a newly initialised array. 因此,这与传递引用无关,而与适当的数组初始化有关,并且知道新初始化数组的默认值。

Specifically, you are using a for-each construct to loop over the array. 具体来说,您正在使用for-each构造遍历数组。 This construct performs an operation on every object in a collection/array. 此构造对集合/数组中的每个对象执行操作。

Therefore, this code: 因此,此代码:

AnotherObject [] anotherObjectArray = new AnotherObject [1];
for (AnotherObject i: anotherObjectArray){
    i.init(72,72);
}

is equivalent to this code: 等效于以下代码:

AnotherObject [] anotherObjectArray = new AnotherObject [1];
for(int count=0; count <  anotherObjectArray ; count++){
    AnotherObject tempObj = anotherObjectArray[i]; // This is null, because anotherObjectArray[i] hasn't been initialised yet
    tempObj.init(72,72); // This is where we get the NullPointerException :(
}

Can you see the problem? 你看到问题了吗? You are attempting to perform an operation on null, hence the NullPointerException 您正在尝试对null执行操作,因此NullPointerException

I believe what you actually intended was this: 我相信您的实际意图是:

AnotherObject [] anotherObjectArray = new AnotherObject [1];
for(int count=0; count <  anotherObjectArray ; count++){
    AnotherObject tempObj = new AnotherObject(); // Here we create the new object
    tempObj.init(72,72); // Initialise the newly created object
    anotherObjectArray[i] = tempObj; // Now we store in the array :)
}

I hope I explained this clearly enough, but please ask for clarification if I haven't :) 我希望我已经足够清楚地解释了这一点,但是请问是否需要澄清:)

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

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