2016-06-27 7 views
0

Я новичок программист 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, который говорит:

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

Итак, я пытался сделать это в моей основной программе:

MyRecordArray[0] = new MyLibrary.MyRecord(); 

но дает эту ошибку:

an enclosing instance that contains MyLibrary.MyRecord is required

Это сообщение об ошибке привела меня к this Stack Exchange question, который говорит:

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

Таким образом, в соответствии с этим ответом, я добавил эти две линии к моей программе:

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]; 

Но ничего не работает, и я чувствую, Теперь я хватаюсь за соломинку. У меня возникает ощущение, что правильный набор глаз может решить это довольно быстро.

ответ

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

Надеюсь, это поможет.

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

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

Вложенный класс MyRecord содержит скрытую ссылку на внешний класс MyLibrary и, следовательно, должен быть связан с экземпляром MyLibrary. Таким образом, MyRecord может получить доступ к частным членам MyLibrary.

MyLibrary.MyRecord myrecord = mylibrary.new MyRecord(); 

Вау, это забавный синтаксис.За все годы программирования Java я никогда не использовал такую ​​конструкцию. Как правило, вы должны создавать объекты внутренних классов (MyRecord) во внешнем классе (MyLibrary). Еще одна распространенная вещь - объявить внутренний класс как static, который устранит необходимость в экземпляре внешнего класса.


MyRecord[] TenRecs = new MyRecord[10]; 

Это создаст массив, в котором все элементы равны нулю. Вы должны инициализировать каждый из них (например, с помощью цикла).

+0

Допустим, это забавный синтаксис. Я просто пытался следовать синтаксису этого другого ответа, который собрал 50 upvotes. –

Смежные вопросы