我是一名新手Java程序员,试图使用在不同文件中定义的类。所以,我已经写了这两个.java文件:
首先,有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);
}
}
然后,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);
}
}
}
我没有问题让方法工作得很好;现在我的目标是创建一个数组,其中数组的每个成员都有一个整数和字符。 (注意:我没有找到更好的方法来实现这个目标;我只是用这个简单的例子来试图让这个工作起来)。
当我尝试运行我的程序时,我得到了:
显示java.lang.NullPointerException
我对此进行了研究,发现了this page,其中说:
如果我们尝试在创建对象之前访问它们,则会发生运行时错误。例如,以下语句在运行时抛出NullPointerException,表示[this array]尚未指向[an]对象。必须使用类的构造函数实例化对象,并且应按以下方式将其引用分配给数组元素。
studentArray[0] = new Student();
所以,我试图在我的主程序中这样做:
MyRecordArray[0] = new MyLibrary.MyRecord();
但是出现了这个错误:
需要包含MyLibrary.MyRecord的封闭实例
该错误消息引导我this Stack Exchange question,其中说:
你必须创建一个X类(外部类)的对象,然后使用objX.new InnerClass()语法来创建一个Y类的对象。
X x = new X();
X.Y y = x.new Y();
所以,按照这个答案,我已经将这两行添加到我的程序中:
MyLibrary mylibrary = new MyLibrary();
MyLibrary.MyRecord myrecord = mylibrary.new MyRecord();
这些线条没有给出任何警告或编译错误,所以我觉得我更接近一步,但我还是想弄清楚如何制作阵列。我知道如果我想制作一个整数数组,我会这样做:
int[] TenInts = new int[10];
所以,我尝试过这样的事情:
myrecord[] TenRecs = new myrecord[10];
MyRecord[] TenRecs = new MyRecord[10];
但是没有任何工作,我觉得我现在正在抓稻草。我觉得正确的眼睛可以很快解决这个问题。
答案 0 :(得分:1)
您需要将内部类声明为静态。
您可以按照以下方式修改代码以满足您的要求:
这是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);
}
}
这是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();
}
}
您可以按如下方式创建内部类的实例:
TenRecords[i] = new MyLibrary.MyRecord();
希望这有帮助。
答案 1 :(得分:1)
嵌套类MyRecord
包含对外部类MyLibrary
的隐藏引用,因此必须与MyLibrary
的实例关联。这种方式MyRecord
可以访问MyLibrary
的私人成员。
MyLibrary.MyRecord myrecord = mylibrary.new MyRecord();
哇,这是有趣的语法。在我多年的java编程中,我从未使用过这样的构造。通常,您将在外部类(MyRecord
)中创建内部类(MyLibrary
)的对象。另一个常见的事情是将内部类声明为static
,这将消除对外部类的实例的需要。
MyRecord[] TenRecs = new MyRecord[10];
这将创建一个所有元素都为NULL的数组。你必须初始化每一个(例如循环)。
答案 2 :(得分:0)
您需要注意几点。 首先,实例内部类和静态内部类之间存在差异。
实例内部类,声明时没有static
修饰符,
public class OutterClass {
public class InstanceInnerClass {}
}
应该像这样创建:
OutterClass outter = new OutterClass();
InstanceInnerClass iInner = outter.new InstanceInnerClass();
静态内部类,使用static
修饰符
public class OutterClass {
public static class StaticInnerClass {}
}
应该像这样创建:
StaticInnerClass sInner = new OutterClass.StaticInnerClass();
其次,在填充之前访问了一个数组条目
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);
}
答案 3 :(得分:0)
如果初始化MyRecord[10]
,则数组具有空对象。您仍然必须将数组中的每个元素初始化为新的MyRecord
对象。否则,您将获得NPE
。
一种方法是:List<MyRecord> TenRecs = new ArrayList<MyRecord>();
TenRecs.add( new MyRecord() );
或for ( int i = 0; i < 10; i++ ) TenRecs[i] = new MyRecord();
如果你添加了一个导入语句:import mymainpackage.MyLibrary.MyRecord;
你不需要mylibrary.new MyRecord();
只做new MyRecord();
答案 4 :(得分:0)
您必须在初始化之前在数组中创建每个对象。请参阅this link。
像这样创建每个对象。
MyLibrary outer = new MyLibrary();
TenRecs[i] = outer.new MyRecord();
完整代码:
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);
}