null pointer exception

User avatar
seal58
Posts: 351
Joined: Fri Jul 12, 2019 5:28 pm
Location: Rostock, Germany
Contact:

null pointer exception

Post by seal58 »

Hi there,
I just try to write a class, that should create and manage data entries. Until now no methods for later use are enclosed. At the moment only target is creating that array.
Unfortunately Java compiler throws a NullPointerEcxeption and I don't find out why.
So I'd be very happy for any help.

Roland

This is the code:

Code: Select all

    RingSpeicher rs = new RingSpeicher(8, 11);
//============================================================
public class RingSpeicher 
{
   int 
      dataUsed=0,   // number of filled data places
      dataLen=1,    // total number of data places
      chs=1,        // number of channels
      initialXpos=-1;
   
   ChannelData[]  waveData; // creates a variable for channel data arrays
   
   public RingSpeicher (int channelCount, int dataCount)
   {
      this.chs = channelCount;
      this.dataLen = dataCount;
      if (rslog) Log("rs has got parameters: ch="+this.chs+" len="+this.dataLen);
      this.waveData = new ChannelData[this.chs]; // initializes the variable for an array of channel data arrays
      for (int c=0; c<this.chs; ++c) {
         this.waveData[c].channelData = new DataSet[dataLen];	// fill each array element with a data array
         for (int index=0; index<dataLen; ++index) {  // set initial values
            this.waveData[c].channelData[index].logicalState = false;
            this.waveData[c].channelData[index].xPos = initialXpos;
         }
      }
   }
//-----------------------------------
   public abstract class DataSet 
   {
      boolean logicalState;
      int xPos;
   }
//------------------------------------   
   public abstract class ChannelData { // creates a data array
      DataSet[] channelData;
   }
//------------------------------------
   public static void main (String[] args)
   {
      
   }

} // class RingSpeicher
nullpointerexception.jpg
nullpointerexception.jpg (204.12 KiB) Viewed 1576 times
Last edited by seal58 on Mon Apr 25, 2022 7:58 am, edited 1 time in total.
ColinP
Posts: 940
Joined: Mon Aug 03, 2020 7:46 pm

Re: null pointer exception

Post by ColinP »

Hi,

I just took a quick look at this but found it very difficult to read, partly because I use whitespace very differently, but mostly because of the use of "this." everywhere. Why are you using this.x when you could just use x?

The other thing I noted was the use of abstract classes. I'm relatively new to Java and haven't built anything yet with enough inheritance for abstract classes to make sense. But as far as I know you can't instantiate an abstract class. But I would have expected that this would produce a compile time error rather than a runtime exception.

I'm not sure if any of the above helps but as I said I was only able to take a quick look.
User avatar
seal58
Posts: 351
Joined: Fri Jul 12, 2019 5:28 pm
Location: Rostock, Germany
Contact:

Re: null pointer exception

Post by seal58 »

Hi Colin,

thanks for your quick response.

With Java I'm still a beginner. In former time I worked with TurboPascal. Now with Java I have to get in Object Oriented Programming. That's a complete other world.

Use of "this." comes from a friend, who works as programmer with other languages than Java. He tried to give me some help. As I understood, "this" should ensure that data are not only valid within actual range (void or class) but in parent range (class RingSpeicher).

I am familiar with creation of arrays with basic types. But I need to combine different types within one data set. Java manual showed me, that abstract classes can be used for that case. In my example I want to build up the data hierarchy:

waveData[]
- channelData[]
-- dataSet
--- boolean logicalState
--- int xPos
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: null pointer exception

Post by UrbanCyborg »

Not 100% sure on this, but it looks to me like you're trying to assign an array variable that you haven't created yet. You created the holder for it, but never created or filled in the values.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
User avatar
seal58
Posts: 351
Joined: Fri Jul 12, 2019 5:28 pm
Location: Rostock, Germany
Contact:

Re: null pointer exception

Post by seal58 »

UrbanCyborg wrote: Mon Apr 25, 2022 9:28 am Not 100% sure on this, but it looks to me like you're trying to assign an array variable that you haven't created yet. You created the holder for it, but never created or filled in the values.

Reid
Hi Reid,
on my view the things are done, you talked of:

2594: holder for array created
2601: array waveData created
2603: array channelData created as content of wavaData[c]
2604: fill channelData[index] with initial values

Just line 2603 makes the problem. I cannot find out the reason yet. In 2601 waveData has got dimensions, so why an index of already 0 is out of range? It looks like line 2601 was not processed.
Do you have any idea?

Roland
ColinP
Posts: 940
Joined: Mon Aug 03, 2020 7:46 pm

Re: null pointer exception

Post by ColinP »

I'm essentially a novice in Java (I only just realized the other day that you can use Strings in switch statements) and am still discovering the more subtle stuff but I have lots of experience using object orientation.

My main influence is Eiffel which is extremely strict and tidy so Java looks a bit messy to me but nothing like as messy as C++!

Normally one only uses "this" to pass a reference to the current object in a message, an example being in VM where you'll see it being used in component initialization. The other use is in disambiguation where x and this.x might be different references but this is extremely rare.

Abstract classes can be built that don't use "abstract" if you like, it's just that the modifier abstract is supposed to stop you instantiating an abstract class by mistake. However in this example the compiler doesn't seem to mind. Which I find confusing as hell. Perhaps try removing the abstract modifier to see if it changes anything?

Yeah Reid, I initially thought it was the classic array reference with no actual array problem but I don't think it is that, though could be wrong as it looks way too complicated and hard to understand.

I ended up changing the code into a form closer to my style so that I could read it more easily...

I also changed the ++c to c++ as it looked weird even though it doesn't alter the semantics.

By the way Roland, I wouldn't use channelData as an identifier for a member inside of a class called ChannelData, it's just too confusing.

The use of the DataSet and ChannelData classes looks more like one would do it in a non OOPL. If it was C they'd be structs. Instead I'd make the data inside those classes private and build methods in them that can be called by the RingSpeicher class.

As an aside, personally I would prefer class members to default to private rather than package-private as is the case in Java. It seems to be concession to C++ programmers maybe.

I keep all data private in my classes and only use methods to access them. Such encapsulation makes bugs far less likely and you can later completely change the internal data mechanisms without it affecting client code.

The code...

waveData[ c ].channelData = new DataSet[ dataLen ];

just feels wrong as it's initializing a ChannelData object externally when you'd normally do that in a constructor within ChannelData.

Code: Select all


public class RingSpeicher 
{
   int dataUsed = 0,   // number of filled data places
   int dataLen = 1;    // total number of data places
   int chs = 1;        // number of channels
   int initialXpos = -1;
   
   ChannelData[] waveData; // creates a variable for channel data arrays
   
   public RingSpeicher( int channelCount, int dataCount )
   {
      chs = channelCount;
      dataLen = dataCount;
      
      if( rslog )
         Log( "rs has got parameters: ch=" + chs + " len=" + dataLen );
      
      waveData = new ChannelData[ chs ]; // initializes the variable for an array of channel data arrays
      
      for( int c = 0; c < chs; c++ )
      {
         waveData[ c ].channelData = new DataSet[ dataLen ];	// fill each array element with a data array
 
         for( int index = 0; index < dataLen; index++ ) 
         {
           // set initial values
            waveData[ c ].channelData[ index ].logicalState = false;
            waveData[ c ].channelData[ index ].xPos = initialXpos;
         }
      }
   }
//-----------------------------------
   public abstract class DataSet 
   {
      boolean logicalState;
      int xPos;
   }
//------------------------------------   
   public abstract class ChannelData 
   { 
      // creates a data array
      DataSet[] channelData;
   }
//------------------------------------
   public static void main( String[] args )
   {
      
   }

} // class RingSpeicher
User avatar
seal58
Posts: 351
Joined: Fri Jul 12, 2019 5:28 pm
Location: Rostock, Germany
Contact:

Re: null pointer exception

Post by seal58 »

With help of your comments I rebuilt class code a little bit.
- Now waveData array elements should contain channalData arrays.
- I removed "abstract" and "public" modifiers for type definition classes.

Unfortunately it changed nothing. Exactly at same command (line 2610) NullPointerException appears. That's really strange because log in line 2606 confirms that array length is 8.

If my way seems to be too complicated, could you recommend a simple way to create a non basic type array, please?

actual code:

Code: Select all

  RingSpeicher rs = new RingSpeicher(8, 50);
//============================================================
public class RingSpeicher 
{
   int 
      dataUsed=0,   // number of filled data places
      dataLen=1,    // total number of data places
      chs=1,        // number of channels
      initialXpos=-1;
   
   ChannelDataClass[]  waveData; // object for an array of ChannelDataClass type
   DataSetClass[] tempChannelDataArray;   // object of DataSet[] type
   
   public RingSpeicher (int channelCount, int dataCount)
   {
      chs = channelCount;
      dataLen = dataCount;
      if (rslog) 
         Log("--- rs has got parameters: ch="+chs+" len=" + dataLen);

      waveData = new ChannelDataClass[chs]; // initializes an array of channel data arrays
      if (rslog) 
         Log("--- rs, waveData initialized with len=" + waveData.length);

      for (int c = 0; c < chs; c++) 
      {  // fill waveData with content
         waveData[ c ].channelData = tempChannelDataArray;
         waveData[ c ].channelData = new DataSetClass[ dataLen ];

         for (int index = 0; index < dataLen; index++) 
         {  // set initial values
            waveData[ c ].channelData[ index ].logicalState = false;
            waveData[ c ].channelData[ index ].xPos = initialXpos;
         }
      }
   }
//-----------------------------------
   class DataSetClass 
   {
      boolean logicalState;
      int xPos;
   }
//------------------------------------   
   class ChannelDataClass { // creates a data array for one channel
      DataSetClass[] channelData;
   }
//------------------------------------
   public static void main (String[] args)
   {
      
   }

} // class RingSpeicher
JRE messages and logs:
nullpointerexception_k2.jpg
nullpointerexception_k2.jpg (282.18 KiB) Viewed 1549 times
ColinP
Posts: 940
Joined: Mon Aug 03, 2020 7:46 pm

Re: null pointer exception

Post by ColinP »

I'm guessing here but I think you are trying to do something like this...

Code: Select all


// VM Initialize()


@Override
public void Initialize()
{
   // add your own code here

   RingStorage rs = new RingStorage( 8, 50 );

}

//=====================================================

public class RingStorage
{

public RingStorage( int channelCount, int dataCount )
{
   channelArray = new ChannelData[ channelCount ];
   
   for( int i = 0; i < channelArray.length; i++ )
      channelArray[ i ] = new ChannelData( dataCount );
}

public ChannelData getChannel( int index )
{
   return channelArray[ index ];
}

private ChannelData[] channelArray;

}

//=====================================================

public class ChannelData
{
public ChannelData( int dataCount )
{
   logicalState = false;
   xPos = -1;
   waveData = new int[ dataCount ];
}

public boolean getLogicalState()
{
   return logicalState;
}

public void setLogicalState( boolean value )
{
   logicalState = value;
}

public int getxPos()
{
   return xPos;
}

public void setXPos( int value )
{
   xPos = value;
}

public int getNumSamples()
{
   return waveData.length;
}

public int getSample( int index )
{
   return waveData[ index ]; 
}

public void setSample( int index, int value )
{
   waveData[ index ] = value; 
}

private boolean logicalState;
private int xPos;
private int[] waveData;

}
//=====================================================
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: null pointer exception

Post by UrbanCyborg »

Here's a slightly changed, reformatted version of your code:

Code: Select all

    private boolean rslog = false;
    RingSpeicher rs       = new RingSpeicher(8, 11);

    public class RingSpeicher {
        int           dataUsed    = 0;
        int           dataLen     = 1;
        int           chs=1;
        int           initialXpos = -1;
        ChannelData[] waveData;
   
        public RingSpeicher(int channelCount, int dataCount) {
            chs     = channelCount;
            dataLen = dataCount;
            if(rslog) 
                Log("rs has got parameters: ch=" + chs + " len=" + dataLen);
            waveData = new ChannelData[chs];
            for(int c = 0; c < chs; ++c) {
                waveData[c].channelData = new DataSet[dataLen];
                for(int index = 0; index < dataLen; ++index) {
                    waveData[c].channelData[index].logicalState = false;
                    waveData[c].channelData[index].xPos         = initialXpos;
                }
            }
        }
        public class DataSet {
            boolean logicalState;
            int     xPos;
        }
        public class ChannelData { 
            DataSet[] channelData;
        }
        public static void main(String[] args) { }

    } // class RingSpeicher
Obviously, I have yet another preferred style :D . This fails on exactly the same lines as your original, but I don't think they're the problem. The problem happens a few lines earlier. You haven't defined a constructor for your ChannelData class, and the default constructor can't take an argument. Also, class DataSet doesn't create anything; it defines a class. Nothing is created until you instantiate a concrete class from it with new, and that will, again, use the default constructor, since you haven't defined one.

Speaking to the more general question you asked, the basic problem in OOP design is to partition the elements in your problem space so that things that represent something important in that space have all the data, and all the operations on that data, grouped into classes. Obviously, there's more than one way to do this; you want to find one that hides the mess behind an interface while exposing only the operations that need doing. That likely sounds like just so much wind, but it is the fundamental design goal. If you don't see why various pieces of data belong together, or what the obvious operations are, you probably don't have a good candidate for a class, and should look at a different breakdown.

Incidentally, am I right in supposing that this is code for a circular, or ring buffer? RingSpeicher bedeutet ich nicht. I took two years of German forty-five years ago, haven't used it since, and would only embarrass myself and add to the general hilarity if I said more auf Deutsch. :oops: I was just guessing that "ring memory" meant, in common English computer parlance, "ring buffer."

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
User avatar
seal58
Posts: 351
Joined: Fri Jul 12, 2019 5:28 pm
Location: Rostock, Germany
Contact:

Re: null pointer exception

Post by seal58 »

What a great service! I thank you both very much. :)

Colin's example does not match exactly my wanted structure, but it shows just the procedure, which Reid tryed to explain to me. I assume, now I understood how to use classes with contructors.

Later this day I will get into the code. I'll come back here to report results.

@UrbanCyborg
Right! "RingSpeicher" means "circular storage" or "ring buffer". At the beginning of work on this class I used German words in order to make classes better visible for me.
A cycle storage was talked about in another topic some days ago. Mine will not handle samples. Thats why I need a different data set structure.

Until later!
Roland
Post Reply

Return to “Module Designer”