2013-10-22 51 views
0

我在名爲actors的單獨類中有一個名爲「filmList」的ArrayList,我想在切換中使用第2種情況調用newActor.filmList.get(ⅰ);但我不斷收到編譯器的錯誤object may not be initialized。如果我把同一行放在開關盒1中,它工作正常,但在情況2我得到錯誤。有人能告訴我如何從構造函數創建newActor對象的外部調用對象的方法,我將永遠感激,它正在進入我的頭腦,我的講師在解釋事情時非常糟糕。謝謝。如何在對象創建的範圍之外調用對象的方法

public class ActorsMain { 

public static void main(String[] args) { 

    Scanner kb = new Scanner(System.in); 

    String fName=""; 
    String lName=""; 
    String address=""; 
    int age; 
    String filmEntry=""; 
    String code=""; 


    ArrayList actors = new ArrayList(); 
    ArrayList films = new ArrayList(); 
    int choice=0; 
    while(choice!=3){ 
    System.out.println("Make your selection.\n1. Add Actor\n2. List Actors"); 
    choice=kb.nextInt(); 

    switch (choice){ 

    case 1: 
      System.out.println("\nPlease enter the actors first name:"); 
      fName=kb.next(); 
      System.out.println("Please enter the actors second name:"); 
      lName=kb.next(); 
      System.out.println("Please enter the actors address:"); 
      address=kb.next(); 
      System.out.println("Please enter the actors age:"); 
      age=kb.nextInt(); 
      kb.nextLine(); 

      for(int a=0;a<10;a++){ 
      System.out.println("Please enter the actors film.\nType 'Stop' to stop entering films."); 
      filmEntry=kb.nextLine(); 
      //kb.nextLine(); 
       if(filmEntry.equalsIgnoreCase("stop")){ 
        break; 
       } 
       else { 

        Films filmObject = new Films(filmEntry,code); 
        films.add(filmObject); 
       } 
      } 


      Actors newActor = new Actors(fName,lName,address,age); 
      actors.add(newActor); 

      newActor.setFilm(films); 
      films.clear(); 
      break; 

    case 2: 

     break; 


    } 
    } 





}  

}

+0

請在問題文本中使用格式和英語,但不清楚您要求的內容 – iluxa

+2

_...我的講師在解釋>東西時很糟糕 - 他不是唯一一個 –

+0

道歉,我不確定這裏的格式化是如何工作的。 – Nodstuff

回答

0

您必須在switch語句的範圍之外聲明newActor。在交換機的第二種情況下,newActor不存在。

int c = 0; 
switch (c) { 
    case 1: 
     Object obj = new Object(); 
     break; 
    case 2: 
     System.out.println(obj.toString()); // obj only exists in case 1 
     break; 
} 

這其實是有點奇特,也許別人可以解釋爲什麼,但是你所得到的錯誤似乎是特別的switch語句。如果您嘗試執行以下操作:

int c = 0; 
if (c == 1) { 
    Object obj = new Object(); 
} else if (c == 2) { 
    System.out.println(obj.toString()); 
} 

你會得到一個不同的錯誤,說「找不到符號」,這是更重要的一點。顯然,交換機內的情況共享範圍,以便他們可以「看到對方」。我認爲這與無間斷轉場有關。開關都是一個模塊,箱子只能確定入口點。

我不確定你要做什麼來告訴你在哪裏放置你的newActor聲明,但現在的重點是你的交換機中的情況2不能使用它。它只存在於案例1中。

此外,你不應該使用一個開關這麼長的語句。你至少應該重構它,所以它使用if語句。開關只是不適合這種事情。這意味着它們是用大量的可能性,小報表每種情況下長期條件:

char operator = '*'; 
int leftNumber = 5; 
int rightNumber = 9; 

switch (operator) { 
    case '+': System.out.println(leftNumber + rightNumber); 
       break; 
    case '-': System.out.println(leftNumber - rightNumber); 
       break; 
    case '*': System.out.println(leftNumber * rightNumber); 
       break; 
    case '/': System.out.println(leftNumber/rightNumber); 
       break; 
    case '^': System.out.println(Math.pow(leftNumber, rightNumber)); 
       break; 
    default: System.out.println("Unknown operator"); 
} 

作爲一個長期側面說明,你是不是傳遞一個類型參數到您的ArrayList。 Java不知道你的ArrayList包含演員和電影,除非你這麼說:

ArrayList<Actors> actors = new ArrayList<Actors>(); 

的ArrayList和其他泛型應該與<E>一個括號內的參數,其中E是在所需類類型的元素被初始化陣列。

類型參數有點像擴展類。 ArrayList類將在源代碼中包含E,當您將Actor傳入E參數時,E將被替換爲Actor。

class ArrayList<E> { 
    Object[] array = new Object[some_length]; 
    public E get(int index) { 
     return (E)array[index]; 
    } 
} 

成爲

class ArrayList<Actor> { 
    Object[] array = new Object[some_length]; 
    public Actor get(int index) { 
     return (Actor)array[index]; 
    } 
} 

注意,即使在當時是否不是Java知道該ArrayList包含演員的應用程序運行時仍然是模糊的,由於仿製藥的實現方式。它們使用稱爲擦除的東西來實現。在運行時,無法知道ArrayList是否爲Actor類型。

如果您使用類型參數聲明它們,您將能夠使用get()作爲代碼中的Actor和Films來訪問它們的元素,您現在將無法使用它們。

換句話說,你可以這樣做:

System.out.println(actors.get(aIndex).filmList.get(fIndex)); 

它看起來像你開始嘗試下2的情況下做的,但你也不能在此刻做。如果沒有<Actor><Film>它會告訴你「找不到符號」或「不兼容的類型」,因爲ArrayList包含一個沒有type參數的Object數組。 (它仍然是一個帶有類型參數的Object數組,但是您可以像使用的類型一樣使用它。)

+0

非常感謝,這對我們有很大的幫助。我將嘗試使用if-else語句進行重構,並嘗試使用ArrayList的類型參數來查看我如何繼續。再次感謝,我將與我的課程中的一些人分享這個答案,因爲我從這個答案中學到的東西比在6周內從我的講師那裏學到的要多。 (我不能upvote,但如果我能我會) – Nodstuff

+0

不客氣。如果你想了解更多關於泛型的知識,可以參考一下Java教程:http://docs.oracle.com/javase/tutorial/java/generics/index.html但是泛型非常複雜,你不需要知道除了我所說的正確使用ArrayList之類的東西之外。該教程可能是TMI的方式。我找不到專門針對局部變量範圍的官方文檔,但是有一些關於Google和SO的文檔。一般來說,一個規則是,只要你把東西放在大括號內,只有塊內部和內部塊可以看到它。 – Radiodef

+0

感謝你,我已經把它分類了,我終於可以睡覺了!我不能夠感謝你。我添加了類型的參數,並使用了您提供的System.out,稍加修改它足以讓我明天睡覺並磨光。你先生,是個紳士和學者! – Nodstuff

0

即時猜測你的演員類有一個名爲filmList一個ArrayList,並且希望在某個位置,以得到它的價值。如果是這種情況,您應該在您的Actor類中創建一個getFilmListIndex(int pos)方法,該方法接受索引值並返回您的電影列表存儲的任何對象。假設你的filmList存儲字符串,它可能看起來像這樣。

public String getFilmListIndex(int pos) 
     { 
     return filmList.get(i); 
     } 

然後從您的ActorMain類中調用此方法。

String result = newActor.getFilmListIndex(i); 
+0

感謝您的回答,但我的問題是,當我輸入「newActor.getFilmListIndex」(或任何我嘗試調用的方法)時,newActor以紅色下劃線,並且表示局部變量可能未初始化。如果我在休息之前移動完全相同的陣容,在情況1它工作正常。 – Nodstuff

0

age在聲明時未初始化。在情況1中,它將被設置,但是在情況2中,它不清楚它已經被設置。

你可以給它分配一個虛擬值,當你把它聲明,但通常是大部分範圍變量只有在它們的實際使用&有一個有效的價值更好的做法。

這會建議將所有參與者的詳細信息放入一個單獨的方法中,或者在花括號內(不是很好),並且只在分配值時聲明它們。具有可定義的變量,其中包含未定義的值,虛擬值或過期值,其值爲,可證明不太正確比只有變量聲明的變量聲明的範圍等同於值的有效值&適用。

+0

是的,但年齡僅用於情況1.情況1是添加演員,獲取所有細節並創建一個名爲「newActor」的演員對象,並將其存儲在actorMain中的數組列表中,並創建一個帶有電影標題的電影對象,以及將其存儲在演員課程中的數組列表中。情況2僅打印actorMain中的陣列列表中存儲的演員信息以及演員類中陣列列表中的電影信息。我可以很好地打印演員,但是當我嘗試使用「newActor.filmList.get(i)」在循環中打印電影信息時,它說newActor未初始化。對於文本的牆壁感到抱歉。 – Nodstuff

相關問題