2011-11-11 189 views
4

我剛剛開始學習Java,並且遇到了問題。當試圖運行Android應用程序時,當調用makeResponse方法時,我得到一個NullPointerException。空指針異常Java

代碼提取物(全碼所附在這篇文章的結尾):

private String makeResponse(String input){ 
    //This doesn't work yet. I keep getting null pointer exceptions on the line beginning "int id" line, but can't tell why. 
    String response = "You picked "+input; 
    if (sw==null){ 
     response+=" and sw is null"; //This doesn't activate 
    } 
    if (input==null){ 
     response+=" and input is null"; //This doesn't activate 
    } 
    int id = sw.getIdFromName(input); //If this line (and the following one) are commented out, the method runs with no problem, but neither of the if clauses above trigger. 
    response+=", that has id "+String.valueOf(id); 
    return response; 
} 

(SW是父類的字段,在另一種方法中設定SW是自制類的實例 - 在年底完整的代碼)

唯一的例外是在該行拋出開始「INT ID =」

我對NullPointerException異常初始搜索中對我說,這是「拋出當應用程序試圖在一個地方使用null在那裏需要一個物體。「 - 因此我上面的代碼中的兩個「if」子句嘗試查找哪個對象意外爲空。既然這兩者都不是,我推斷sw.getIdFromName必須返回一個Integer類型的null(如同類似問題:Java: null pointer exception when unboxing Integer?)。不過,我不明白這是怎麼可能的sw.getIdFromName如下圖所示(nameLookup是一個字符串數組,SW的字段):

public int getIdFromName(String name){ 
    for (int i=0;i<267;i++){ 
     if (nameLookup[i].equals(name)){ 
      return i; 
     } 
    } 
    return -1; 
} 

(順便說一句,如果有一個搜索一個更好的方法搜索字詞的字符串數組,我會很感激,如果有人可以告訴我 - binarySearch似乎沒有在字符串數組上定義)。

根據上面鏈接問題中頂級評論者的建議,我嘗試在makeResponse中將「int id」替換爲「Integer id」,但沒有任何效果 - 同一個異常在同一個地方拋出。

任何意見將不勝感激。

從上面鏈接的stackoverflow問題的評論來看,提供一個堆棧跟蹤不會提供任何新的信息,但如果被問到,我會很樂意這樣做。

P.s.這是我的第一個問題,如果我違反了禮節或者犯了錯誤,我很抱歉。

完整的代碼清單:

ConversationActivity.java:

package com.example.Conversation; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.AutoCompleteTextView; 
import android.widget.TextView; 

public class ConversationActivity extends Activity { 
/** Called when the activity is first created. */ 
StationsWrapper sw; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    /**Setting the adapter for the AutoComplete*/ 
    final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.ACTextView1); 
    String[] stationsArray = getResources().getStringArray(R.array.stations); 
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, stationsArray); 
    textView.setAdapter(adapter); 

    /**Code below grabs the data from stations.xml and puts it in a readable object */ 
    this.sw = new StationsWrapper(); 

    /** Code below is to set a click function for the AutoComplete*/ 
    OnItemClickListener ACListener = new OnItemClickListener(){ 

     public void onItemClick(AdapterView<?> parent, View v, int position, 
       long id) { 
      TextView reply = (TextView) findViewById(R.id.reply); 
      reply.setText("working..."); 
      String ChosenStation = (String) parent.getItemAtPosition(position); 
      reply.setText(makeResponse(ChosenStation)); 
      //Toast.makeText(ConversationActivity.this, "You clicked "+parent.getItemAtPosition(position), Toast.LENGTH_SHORT).show(); 
      textView.setText(""); 

     } 
    }; 
    textView.setOnItemClickListener(ACListener); 

} 

private String makeResponse(String input){ 
    //This doesn't work yet. I keep getting null pointer exceptions on the line beginning "int id" line, but can't tell why. 
    String response = "You picked "+input; 
    if (sw==null){ 
     response+=" and sw is null"; //This doesn't activate 
    } 
    if (input==null){ 
     response+=" and input is null"; //This doesn't activate 
    } 
    int id = sw.getIdFromName(input); //If this line (and the following one) are commented out, the method runs with no problem, but neither of the if clauses above trigger. 
    response+=", that has id "+String.valueOf(id); 
    return response; 
} 

} 

StationsWrapper.java:

package com.example.Conversation; 


import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

public class StationsWrapper { 

    private int[][] stats; 
    private String[] nameLookup; 

    public StationsWrapper(){ 
     //Constructor. Grabs data from XML, and whacks it into relevant arrays. 
     //stats is an integer array, indexed first by station id (1-267), and then by datatype (0 for line, 1 for zone) 
     final int[][] stats = new int[267][2]; 
     final String[] nameLookup = new String[267]; 

     try { 

      SAXParserFactory factory = SAXParserFactory.newInstance(); 
      SAXParser saxParser = factory.newSAXParser(); 

      DefaultHandler handler = new DefaultHandler() { 

       boolean bline = false; 
       boolean bzone= false; 
       String curStation; 
       int curID; 
       String curLine; 
       String curZone; 

       public void startElement(String uri, String localName,String qName, 
         Attributes attributes) throws SAXException { 

        if (qName.equalsIgnoreCase("STATION")){ 
         curStation=attributes.getValue(0); 
         curID=Integer.parseInt(attributes.getValue(1)); 
        } 

        if (qName.equalsIgnoreCase("LINE")) { 
         bline = true; 
        } 

        if (qName.equalsIgnoreCase("ZONE")) { 
         bzone = true; 
        } 
       } 

       public void endElement(String uri, String localName, 
         String qName) throws SAXException { 
        if (qName.equalsIgnoreCase("Station")){ 
         nameLookup[curID-1]=curStation; 
         int intLine=(convLineToInt(curLine)); 
         stats[curID-1][0]=intLine; 
         int intZone=(convZoneToInt(curZone)); 
         stats[curID-1][1]=intZone; 
        } 
       } 

       public void characters(char ch[], int start, int length) throws SAXException { 

        if (bline) { 
         //System.out.println("Line : " + new String(ch, start, length)); 
         curLine=new String(ch, start, length); 
         bline = false; 
        } 

        if (bzone) { 
         //System.out.println("Zone : " + new String(ch, start, length)); 
         curZone=new String(ch, start, length); 
         bzone = false; 
        } 
       } 

      }; 

      saxParser.parse("c:\\Users\\Jack Jackson\\Coding\\Java\\stations.xml", handler); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     this.stats=stats; 
     this.nameLookup=nameLookup; 

    } 

    public static void main(String[] args){ 
     //Nothing to see here, move it along folks. 
    } 

    public String[] getNameLookup(){ 
     return nameLookup; 
    } 

    public int getIdFromName(String name){ 
     for (int i=0;i<nameLookup.length;i++){ 
      if (nameLookup[i].equals(name)){ 
       return i; 
      } 
     } 
     return -1; 
    } 

    public int returnData(int id, int datapoint){ 
     return stats[id][datapoint]; 
    } 

    public void displayStats(){ 
     for (int i=0;i<267;i++){ 
      for (int j=0;j<2;j++){ 
       System.out.print(stats[i][j]); 
       System.out.print(" "); 
      } 
      System.out.println(""); 
     } 
    } 
    } 
+0

您是否嘗試過調試您的程序?您可以在NullPointerException中斷點,然後查看原因。 –

+0

你可以在仿真器下重現這個嗎?你檢查了堆棧跟蹤嗎? – alf

回答

5

不運行你的代碼,它似乎很可能nameLookup陣列中的一個條目是null,所以試圖撥打nameLookup[i].equals()會拋出一個NullPointerException

如果nameLookup要素可以合法地null,來處理這一種方法是反向的比較順序getIdFromName()

if (name.equals(nameLookup[i])) { 

在任何情況下,我建議您確保這兩個nameLookup本身及其元素已完全初始化。

+0

啊,這是問題所在。我添加了一些更多的測試代碼給getIdFromName,事實證明nameLookup的元素確實爲null。因爲在這種情況下,這絕不應該發生,我必須在我的初始化代碼中遺漏一些東西。現在我知道在哪裏看得更近。感謝您的幫助! – scubbo