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

江枫思渺然 提交于 2021-02-11 15:16:52

问题


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.


回答1:


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.




回答2:


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).




回答3:


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();




回答4:


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);  
    }



回答5:


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);
}


来源:https://stackoverflow.com/questions/38045244/how-to-make-an-array-from-a-class-defined-inside-another-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!