问题
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