2011-11-11 3 views
4

Je commence tout juste à apprendre Java et j'ai rencontré un problème. Lorsque j'essaie d'exécuter une application Android, j'obtiens une exception NullPointerException lorsque la méthode makeResponse est appelée.Null Pointer Exception Java

extrait de code

(code complet en annexe à la fin de cette publication.):

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 est un champ de la classe parent, situé dans un autre procédé sw est une instance d'une classe autodidacte - code complet à la fin)

l'exception est levée à la ligne commençant « int id = »

Ma recherche initiale NullPointerException m'a dit qu'il a été « jeté lorsqu'une application tente d'utiliser null dans un cas où un objet est requis. " - d'où les deux clauses "if" dans mon code ci-dessus, pour essayer de trouver quel objet était de manière inattendue nul. Comme aucun de ces deux ne sont, j'ai conclu que sw.getIdFromName doit renvoyer une valeur nulle de type Integer (comme dans ce problème similaire: Java: null pointer exception when unboxing Integer?). Cependant, je ne vois pas comment cela est possible dans sw.getIdFromName comme indiqué ci-dessous (NAMELookup est un tableau de chaînes, un champ de sw):

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

(Soit dit en passant, s'il y a une meilleure façon de rechercher un Tableau de chaînes pour un terme de recherche, je serais reconnaissant si quelqu'un pourrait me dire - binarySearch ne semble pas être défini sur les tableaux de chaînes). Suite à l'avis du meilleur commentateur dans la question ci-dessus, j'ai essayé de remplacer "int id" par "Integer id" dans makeResponse, mais sans effet - la même exception est levée au même endroit.

Tout conseil serait grandement apprécié. A en juger par les commentaires dans la question stackoverflow liée ci-dessus, fournir une trace de pile ne fournirait aucune nouvelle information, mais je serais heureux de le faire si demandé.

P.s. C'est ma première question ici, donc excuses si je fais une violation de l'étiquette ou de l'erreur inepte.

annonces de code complet:

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

Avez-vous essayé de déboguer votre programme? Vous pouvez casser le point sur NullPointerException et ensuite voir pourquoi c'est cause. –

+0

Pouvez-vous reproduire ceci sous émulateur? Avez-vous vérifié une trace de pile? – alf

Répondre

5

Sans l'exécution de votre code, il semble très probable que l'un des nameLookup tableau les entrées sont null, alors essayer d'appeler nameLookup[i].equals() lance un NullPointerException.

Si des éléments de nameLookup peuvent légitimement être null, d'une façon de gérer cela est d'inverser l'ordre de la comparaison dans getIdFromName():

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

Dans tous les cas, je vous recommande de vérifier que les deux nameLookup lui-même et ses éléments sont entièrement initialisés.

+0

Ah, c'était le problème. J'ai ajouté un peu plus de code de test à getIdFromName, et il s'avère que les éléments de nameLookup étaient en effet null. Puisque, dans ce cas, cela ne devrait jamais arriver, j'ai dû manquer quelque chose dans mon code d'initialisation. Maintenant, je sais où regarder de plus près. Merci de votre aide! – scubbo