Null Pointer Exception in JUnit test - java

Whenever I try to test my code with JUnit, I receive a NullPointerException - even though I don't get that exception when I run the actual program. The line that gives me the exception is:
assertEquals(0.0, TweetClassification.tweetType[TweetClassification.SIGNIF_OTHER].likelihoodA);
The beginning of the TweetClassification class it's testing is as follows:
public class TweetClassification
{
// CONSTANTS =============================================
public static final int TCNUMBER = 5; // number of TweetCategories (including the null category)
// using constants to indicate the names of the TweetCategories, so that they could be renumbered
public static final int NULLTWEET = 0;
public static final int SIGNIF_OTHER = 1;
public static final int FRIENDS = 2;
public static final int WORK = 3;
public static final int FOOD = 4;
public static final TweetCategory[] tweetType = new TweetCategory[TCNUMBER];
...
(TweetCategory is another class that is defined separately within the package.) So I realize that this code initializes the array but not its members, and that's probably why I'm getting the exception(?) But the thing is, I do initialize the members of the array within the main method of TweetClassification, as follows:
for (int i=0; i<TCNUMBER; i++)
{
tweetType[i] = new TweetCategory();
}
But if I try to move this for loop outside the main method with the constants I get a syntax error - I presume you're not supposed to use a for loop outside of a method. So I'm not sure how to initialize the class properly for JUnit to work - either I do it outside the main method and get a syntax error, or I do it inside the main method and get a NullPointerException. Any ideas?

You need to move the init code into a static initializer block, like this:
public class TweetClassification
{
//...
public static final TweetCategory[] tweetType = new TweetCategory[TCNUMBER];
static
{
for (int i=0; i<TCNUMBER; i++)
{
tweetType[i] = new TweetCategory();
}
}
//...
}
This ensures that the static variable is initialized properly when the class is loaded (i.e. before it is first used anywhere within your program or tests).

Yo might find some use of the static initialzier block:
private static Integer arr[] = new Integer[2];
static {
for (int i = 0; i < 2; i++) {
arr[i] = 2;
}
}
public static void main(String[] args) {
System.out.println(arr[1]);
}
Ouputs:
2
This is proper java and is meant exactly for initializing static variables, though it is not very commonly used.

Related

Find the minimum of a set of data input from the keyboard

I have an algorithm in my textbook written in pseudocode which is then supposed to be "implemented to a Java method". It goes like this:
read min;
while not eoln do
read x
if x < min then
min <- x
end if
end while
print min;
Then I'm given this code:
import java.util.Scanner;
int min() {
Scanner input = new Scanner(System.in);
System.out.println("x=? (999 to end)");
int x = input.nextInt();
int min = x;
while (x!=999) {
System.out.println("x=? (999 to end)");
x = input.nextInt();
if (x < min) {
min = x;
}
}
return min;
}
I put everything below import.Scanner inside of the main method and inside of a class like this:
public class MyAlgorithm {
public static void main(String[] args) {
// code here
}
}
But then I get this error message in Terminal:
MyAlgorithm.java:7: error: ';' expected
int min() {
^
1 error
Am I missing something? If I put the semicolon there, the whole thing just won't work.
It seems like you put your min method inside of main, this is defining methods from within other methods which will not work properly and cannot compile. The main method is the commands you want to run as soon as you start your program, any other functions in the class should be declared outside of it, and if you want them to run in main you do a method call.
it should look something like this:
import java.util.Scanner;
public class MyAlgorithm {
int min() {
//(min code)
}
public static void main(String[] args) {
// code here
//corrected according to Uli's comment
MyAlgorithm m = new MyAlgorithm();
int result = m.min();
}
}
I suggest reading up on how java programs are structured. Here's an article on methods.
Don't put your method min() inside the main() method. In Java, you can not define a method inside a method. In Java, you need an object to call its methods (Except you make the methods static). So your final Code looks something like this.
import java.util.Scanner;
public class MyAlgorithm {
public static void main(String[] args) {
MyAlgorithm m = new MyAlgorithm ();
m.min();
}
int min(){
//Your min code goes here
return min_value;
// min_value is the same as your min variable. It has another name to
// prevent name collisions
}
}
If you are allowed to use static methods, (which I don't think) you can use the following alternative:
static int min(){
//Your min code goes here
return min_value;
// min_value is the same as your min variable. It has another name to
// prevent name collisions
}
public static void main(String[] args) {
int result = MyAlgorithm.min();
}

How to make an array from a class defined inside another class

I am a novice Java programmer trying to use classes defined in a different file. So, I've written these two .java files:
First, there's MyLibrary.java:
package mymainprogram;
public class MyLibrary {
public class MyRecord {
int number;
char letter;
}
public static int TriplePlusThree(int input_number) {
return ((input_number*3) + 3);
}
}
Then, MyMainProgram.java:
package mymainprogram;
import java.util.Scanner;
public class MyMainProgram {
public static void main(String[] args) {
Scanner keyread = new Scanner(System.in);
System.out.print("Enter Number to Process: ");
int num = keyread.nextInt();
int result = MyLibrary.TriplePlusThree(num);
System.out.println("3x + 3 = "+result);
String letters = "ABCDEFGHIJ";
MyLibrary.MyRecord[] TenRecs = new MyLibrary.MyRecord[10];
for (int i = 0; i < 10; i++) {
TenRecs[i].number = i; //NullPointerException here
TenRecs[i].letter = letters.charAt(i);
}
}
}
I had no problem getting the method to work just fine; now my goal is to create an array where each member of the array has an integer and character. (Note: I'm not looking for better ways to accomplish this objective; I'm merely using this trivial example to try to get this working).
When I tried to run my program, I got:
java.lang.NullPointerException
I researched this, and found this page, which says:
If we try to access the objects even before creating them, run time errors would occur. For instance, the following statement throws a NullPointerException during runtime which indicates that [this array] isn't yet pointing to [an] object. The objects have to be instantiated using the constructor of the class and their references should be assigned to the array elements in the following way.
studentArray[0] = new Student();
So, I tried to do that in my Main Program:
MyRecordArray[0] = new MyLibrary.MyRecord();
but that gives this error:
an enclosing instance that contains MyLibrary.MyRecord is required
That error message led me to this Stack Exchange question, which says:
you have to create an object of X class (outer class) and then use objX.new InnerClass() syntax to create an object of Y class.
X x = new X();
X.Y y = x.new Y();
So, in accordance with that answer, I've added these two lines to my program:
MyLibrary mylibrary = new MyLibrary();
MyLibrary.MyRecord myrecord = mylibrary.new MyRecord();
Those lines don't give any warnings or compilation errors, so I feel like I'm one step closer, but I'm still trying to figure out how to make an array. I know if I wanted to make an array of integers, I would simply do this:
int[] TenInts = new int[10];
So, I've tried things like:
myrecord[] TenRecs = new myrecord[10];
MyRecord[] TenRecs = new MyRecord[10];
But nothing is working, and I feel like I'm grasping at straws now. I get the feeling that the right set of eyes could solve this pretty quickly.
You need to declare the inner class as static.
You can modify the code as follows to suit your requirements:
This is the code for MyLibrary
public class MyLibrary {
public static class MyRecord{
int number;
char letter;
public MyRecord(){
number = 0;
letter = '\0';
}
public MyRecord(int number, char letter){
this.number = number;
this.letter = letter;
}
}
public static int TriplePlusThree(int input_number){
return (input_number * 3 + 3);
}
}
This is the code for the MyMainProgram
import java.util.Scanner;
public class MyMainProgram {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Enter number to process");
int num = in.nextInt();
System.out.println("3x + 3 = " + MyLibrary.TriplePlusThree(num));
String letters = "ABCDEFGHIJ";
MyLibrary.MyRecord[] TenRecords = new MyLibrary.MyRecord[2];
for (int i=0; i<TenRecords.length; i++){
TenRecords[i] = new MyLibrary.MyRecord();
TenRecords[i].number = i;
TenRecords[i].letter = letters.charAt(i);
}
// Printing class records
for (int i=0; i<TenRecords.length; i++){
System.out.println("Printing records of record " + i + " : ");
System.out.println("Number : " + TenRecords[i].number);
System.out.println("Letter : " + TenRecords[i].letter);
}
in.close();
}
}
You can create the instance of the inner class as follows:
TenRecords[i] = new MyLibrary.MyRecord();
Hope this helps.
The nested class MyRecord contains a hidden reference to the outer class MyLibrary and therefore must be associated with an instance of MyLibrary. This way MyRecord can access private members of MyLibrary.
MyLibrary.MyRecord myrecord = mylibrary.new MyRecord();
Wow, this is funny syntax. In all my years of java programming, I never used such a construct. Typically, you would create objects of inner classes (MyRecord) within the outer class (MyLibrary). Another common thing is to declare the inner class as static which would eliminate the need for an instance of the outer class.
MyRecord[] TenRecs = new MyRecord[10];
This will create an array where all the elements are NULL. You have to initialize each of them (e.g. with a loop).
If you initialize MyRecord[10] the array has null objects. You still have to initialize each element in the array to a new MyRecord object. Otherwise you will get the NPE.
one way to do is : List<MyRecord> TenRecs = new ArrayList<MyRecord>();
TenRecs.add( new MyRecord() );
or for ( int i = 0; i < 10; i++ ) TenRecs[i] = new MyRecord();
also if you add an import statement : import mymainpackage.MyLibrary.MyRecord; You don't need to do mylibrary.new MyRecord(); just do new MyRecord();
You have to create each object in array before initialize. Refer to this link.
Create each object like this.
MyLibrary outer = new MyLibrary();
TenRecs[i] = outer.new MyRecord();
Full code:
MyLibrary.MyRecord[] TenRecs = new MyLibrary.MyRecord[10];
for (int i = 0; i < 10; i++) {
MyLibrary outer = new MyLibrary();
TenRecs[i] = outer.new MyRecord();
TenRecs[i].number = i;
TenRecs[i].letter = letters.charAt(i);
}
There are several points you need to note.
First, difference between a instance inner class and a static inner class.
An instance inner class, declared without static modifier,
public class OutterClass {
public class InstanceInnerClass {}
}
should be created like this:
OutterClass outter = new OutterClass();
InstanceInnerClass iInner = outter.new InstanceInnerClass();
while a static inner class, declared with static modifier,
public class OutterClass {
public static class StaticInnerClass {}
}
should be created like this:
StaticInnerClass sInner = new OutterClass.StaticInnerClass();
Secondly, you accessed an array entry before it is filled
MyLibrary library = new MyLibrary();
MyLibrary.MyRecord[] TenRecs = new MyLibrary.MyRecord[10];
for (int i = 0; i < 10; i++) {
// Create new instance
TenRecs[i] = library.new MyRecord();
TenRecs[i].number = i;
TenRecs[i].letter = letters.charAt(i);
}

java class initialize order, how it works?

package ali;
public class test {
public static int n = 99;
public static test t1 = new test("t1");
public static test t2 = new test("t2");
public static int i = 0;
public static int j = i;
{
System.out.println("construct block");
}
static {
System.out.println("static construct block");
}
public test(String str){
System.out.println((++j) + ":" + " i="+ i + " n="+n+str);
n++;i++;
}
public static void main(String [] args){
test test1 = new test("initl");
}
}
after running:
construct block
1: i=0 n=99t1
construct block
2: i=1 n=100t2
static construct block
construct block
1: i=0 n=101initl
Who can tell me how it works?
why there is no "static construct block" when t1 and t2 ware created?
why i and j changed to the default ,but n still unchanged?
static variables/blocks are executed/initialized as they appear (usually).
your output and why? :
When the class is loaded and during its initialization, the following lines will be executed
public static test t1 = new test("t1");
public static test t2 = new test("t2");
which in-turn create new Test objects, but since the class is already under initialization, the above lines are not executed again.
So,
you get
construct block
1: i=0 n=99t1
construct block
2: i=1 n=100t2
Next, the static block executes
static construct block
Now when you create an object of Test in main(), you will have
construct block
1: i=0 n=101initl
When this class (which really should have a capitalized name) is loaded, the static initializers are invoked in the order in which they appear in the source code. This means that the new test("t?") object creations happen before the explicit static block.

Getting value to display for Java CurrentAccount class

package bankAccount;
public class CurrentAccount {
int account[];
int lastMove;
int startingBalance = 1000;
CurrentAccount() {
lastMove = 0;
account = new int[10];
}
public void deposit(int value) {
account[lastMove] = value;
lastMove++;
}
public void draw(int value) {
account[lastMove] = value;
lastMove++;
}
public int settlement() {
int result = 0;
for (int i=0; i<account.length; i++) {
result = result + account[i] + startingBalance;
System.out.println("Result = " + result);
}
return result;
}
public static void main(String args[]) {
CurrentAccount c = new CurrentAccount();
c.deposit(10);
}
}
At the moment, when I run the class, the expected System.out.println does not appear, and if I simply move public static void main(String[] args) to the top, this generates multiple red points. What is the best way for me to refactor my code so it works in the expected way?
you can have another class called Main in the file Main.java in which you can write your
public static void main(String args[])
and call
c.settlement();
in you main() to print.
Also one more advice,
in your constructor you have
account = new int[10];
which can hold only 10 ints.
in your deposit() and draw() you are not checking the account size. When the value of lastMove is more than 10 , the whole code blows up.
Hence I suggest you to use ArrayList
You never called the settlement method...
public static void main(String args[]) {
CurrentAccount c = new CurrentAccount();
c.deposit(10);
c.settlement();
}
I have the feeling that you come from some non-OOP language, like C or PHP. So some explanation:
The main method is static: that means it "exists" even when there is no object instance created, it can be thought of as if it belonged to the class instance.
on the contrary, for the other methods to "work", an instance is required.
This way the main method can be (and is actually) used as the entry point of the application
It is executed, and when it exists, (if no other threads are left running) the application terminates.
so nothing else is run that is outside of this method just by itself...
so if you don't call c.settlement(); - it won't happen...
Other notes:
Running main doesn't create an instance of the enclosing class
with new CurrentAccount(), you create an object instance, which has states it stores, and can be manipulated
be careful with arrays, they have to be taken care of, which tends to be inconvenient at times...
Why do you expect the printed output to appear? You don't actually call the settlement method, so that command is not executed.
You did not call settlement.. so nothing appears
if you add c.settlement... it is fine..
You have not called deposit() and settlement() in the main method untill you call, You cannot get expected output.

Get and set methods not changing the array

I have extended a class in hope to store a global array (make the array within the class be seen by another object) by using the set1sub(sub.local) method
public class BattleShipsClient extends ShipLocations implements Runnable, BattleShipConstants
{
BattleShipsClient()
{
}
public void placeBoard(int player) throws IOException// this is only called once and not updated when clicked again
{
while(getLocations())
{
while(isWaiting())//true
{
toServer.writeInt(player);
int row = getRowSelected();
int col = getColumnSelected();
int choice=Integer.parseInt(JOptionPane.showInputDialog("Please 1 for a sub, 2 for a battleship and 3 for a destroyer"));
clickCount ++;
if(clickCount >2)
{
setLocation(false);
continueToPlay=true;
}
if (choice ==1 &&sub.placed==false)
{
String orientation =JOptionPane.showInputDialog("please enter your orientations");
if(orientation.equalsIgnoreCase("h"))
{
//row os the same
//column number will be sent, then plus one on the other side
sub.local = new int[2][2];
sub.local[0][0] =row;
sub.local[0][1]=col;
sub.local[1][0]=row;
sub.local[1][1] =col+1;
toServer.writeInt(row);
toServer.writeInt(col);
toServer.writeChar('s');
sub.placed=true;
setp1sub(sub.local);
/*setp1sub(new int[][]{{row,col},
{row,col+1}});*/
grid[row][col+1].setToken(getMyToken());
}
I then have a ship Locations class however when i create a new object of the ship locations class and try to read this array it always is set to [[0, 0], [0, 0]], ive tried making it static and atomic
public class ShipLocations {
int [][] p1sub;
public ShipLocations()
{
p1sub = new int[2][2];
}
public int[][] getp1sub()
{
return p1sub;
}
public void setp1sub(int[][] local) {
for (int i = 0;i <local.length;i++)
{
for(int j = 0;j<local.length;j++)
{
p1sub [i][j]= local[i][j];
}
}
}
}
Whenever you create a new instance of ShipLocations(or a subclass) the constructor is called, which in your case, reinitializes the p1sub array.
In your design, you are overusing inheritance. You should not inherit from a class just to use its methods and variables.
To store a global variable in a class:
public class ShipLocations {
static int [][] p1sub;
static{
p1sub = new int[2][2];
}
public static void setp1sub(...){...}
public static int[][] getp1sub(){...}
}
And then use it by class name instead of creating instances:
int [][] x = ShipLocations.getp1sub();
Though the use of global variables shoud be avoided when possible. It is considered bad design and might be a problem when reusing the code.
The correct way of doing this is to have the ShipLocations object as a local variable in BattleShipsClient and set it when initializing new instance. You will then first create a common ShipLocation object and hand it to every client that should see the same array.

Categories