java 拆分为字符串数组时出现空指针异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33156198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:15:57  来源:igfitidea点击:

Null Pointer Exception when splitting to String Array

javajspmultidimensional-arraynullpointerexceptionfilereader

提问by Gandalf

So I'm trying to populate two arrays from a file reader. Which I believe requires nested loops. I think I'm on the right track but I've been a little stuck since yesterday. The purpose of this program is to initiate the program through a jsp and to read in the values dynamically. Any help would really be appreciated. I think I'm on the right track but I can't seem to finish it on my own. The first line of fxRates.csv should be populated into the currencyCodes Array and the rest of the lines should be populated into the 2d array fxExchangeRates. I got the code to not have any errors but now all I get is this when I try to run the program: enter image description here

所以我试图从文件阅读器填充两个数组。我认为这需要嵌套循环。我认为我在正确的轨道上,但从昨天开始我就有点卡住了。这个程序的目的是通过一个jsp启动程序并动态读入值。任何帮助将不胜感激。我认为我在正确的轨道上,但我似乎无法独自完成它。fxRates.csv 的第一行应填充到currencyCodes 数组中,其余行应填充到二维数组fxExchangeRates 中。我得到的代码没有任何错误,但现在当我尝试运行程序时,我得到的只是这个:在此处输入图片说明

Here is the error log:

这是错误日志:

 Info:   visiting unvisited references
Info:   visiting unvisited references
Info:   visiting unvisited references
Warning:   Ignore WEB-INF/sun-web.xml in archive /G:/School/Java II/Labs/MidtermAD/build/web/, as WLS counterpart runtime xml WEB-INF/glassfish-web.xml is present in the same archive.
Info:   Loading application [MidtermAD] at [/MidtermAD]
Info:   MidtermAD was successfully deployed in 464 milliseconds.
Warning:   StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
    at java.lang.String.split(String.java:2337)
    at java.lang.String.split(String.java:2422)
    at data.FxDataModel.<init>(FxDataModel.java:38)
    at org.apache.jsp.fxCalc_jsp.jspInit(fxCalc_jsp.java:45)
    at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:92)
    at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:210)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access0(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:745)

fxInit.jsp:

fxInit.jsp:

<%@page import="java.io.*"%>
<%@page import="java.util.*"%>
<%@ page import="data.FxDataModel"%>
<%!

private FxDataModel fxDataModel;


        public void jspInit(){
        Properties fxProps = new Properties();


        ServletContext context = getServletContext();
        fxProps.getProperty(FxDataModel.FX_PRP_FILE_NAME_KEY);

        context.getRealPath(context.getInitParameter(FxDataModel.FX_PRP_FILE_NAME_KEY));

        try{
            FileInputStream input = new FileInputStream(FxDataModel.FX_PRP_FILE_NAME_KEY);
            fxProps.load(input);
            input.close();
        }catch(IOException e){

           FileInputStream input = null;
        }
        context.getRealPath(fxProps.getProperty(FxDataModel.FX_RATE_FILE_NAME_KEY));
        try{
            FileInputStream input = new FileInputStream(FxDataModel.FX_RATE_FILE_NAME_KEY);
            fxProps.load(input);
            input.close();
        }catch(IOException e){

            FileInputStream input = null;
        }

        fxDataModel = new FxDataModel(fxProps);


        }
%>

FxDataModel.Java:

FxDataModel.Java:

package data;

import java.util.*;


public class FxDataModel {

   public static final String FX_PRP_FILE_NAME_KEY = "fx.prp.file.name";
   public static final String FX_RATE_FILE_NAME_KEY = "fx.rates.file.name";
   public static final String FX_RATES_FILE_DLMTR_KEY = "fx.rates.file.dlmtr";
   public static final String SRC_AMT_KEY = "src.amt";
   public static final String SRC_CUCY_KEY = "src.cucy";
   public static final String DST_AMT_KEY = "dst.amt";
   public static final String DST_CUCY_KEY = "dst.cucy";

   private Properties fxProps = new Properties();

   private double [][] fxExchangeRates;
   private String[] fxCurrencies;

   public FxDataModel(Properties fxProps)      
         {
          this.fxProps = fxProps;  
          String[] rateStrings;
          String record;
          fxProps .setProperty(FX_RATES_FILE_DLMTR_KEY,"fx.rates.file.dlmtr");
          String delimiter = fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY);
          Scanner reader = new Scanner(FX_RATE_FILE_NAME_KEY);


                  fxCurrencies = reader.nextLine().split(delimiter);

       for( int i = 0 ; i < fxCurrencies.length ; i++ ){

           record= reader.nextLine();
           rateStrings = record.split(delimiter);
           fxExchangeRates[i] = new double[fxCurrencies.length];

          for( int j = 0 ; j < rateStrings.length ; j++ ){

          fxExchangeRates[i][j]= Double.parseDouble(rateStrings[j]);

        }

        reader.close();

       }

         }

         public Properties getFxProps()

         {


           return fxProps;


         }
   public String[] getFxCurrencies(){
       return fxCurrencies;
   }

   public double getFxRate(final String inNumber, final String outNumber){

       int Currency1;
       int Currency2;
       double rate;

        for(Currency1 = 0; Currency1 <getFxCurrencies().length; Currency1++){ 

            if(inNumber.equals(fxCurrencies[Currency1])){
                break;
            }
        }

         for(Currency2 = 0; Currency2 <getFxCurrencies().length; Currency2++){ 

            if(outNumber.equals(fxCurrencies[Currency2])){
                break;
            }
        }


         rate = fxExchangeRates[Currency1][Currency2];
         return rate;

        }

   }

fxCalc.jsp

fxCalc.jsp

    <%@include file="fxInit.jsp"%>
<%      
        Properties fxProps = fxDataModel.getFxProps();
        String srcAmtName = fxProps.getProperty(FxDataModel.SRC_AMT_KEY );
        String dstAmtName = fxProps.getProperty(FxDataModel.DST_AMT_KEY );
        String srcCucyName = fxProps.getProperty(FxDataModel.SRC_CUCY_KEY );
        String dstCucyName = fxProps.getProperty(FxDataModel.DST_CUCY_KEY );
        String Curr1 = request.getParameter(srcAmtName);
        String Curr2 = request.getParameter(dstAmtName);
        String formInput;
        String formOutput;

        String[] currencies = fxDataModel.getFxCurrencies();


        try {

          formInput = request.getParameter(srcAmtName);
          Double formDouble = Double.parseDouble(formInput);
          Double Conversion = fxDataModel.getFxRate(Curr1,Curr2)*formDouble;
          formOutput = String.valueOf(Conversion);

         } catch (NumberFormatException ex) {
             Curr1= Curr2 = currencies[0];
             formInput = ("");
             formOutput = ("");   
         } catch (NullPointerException npe){

            Curr1= Curr2 = currencies[0];
            formInput = ("");
            formOutput = ("");

        }

%>

<html>
    <head>
        <title>F/X Calculator</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>

    <style>

        h1{
            color: white;
            font-family: verdana;
            font-size: 200%;
            font-style: italic;
            text-align: center;
        }
        hr{
            color:white;

        }

        select{
            margin-top: 30px;
            margin-right:10px;
        }
        input{

            margin-top: 30px;
            margin-right:10px;
        }
    </style>


    <body bgcolor = "blue">

        <h1>
            Money Banks F/X Calculator<br>
        </h1>
        <hr>
        <div align="center">
        <form name ="fxCalc" action="fxCalc.jsp" method="POST">


        <select name="<%=srcCucyName%>">
            <% for (String currency : currencies) { %>
              <option value="<%=currency%>" <%=currency.equals(Curr1)?"selected":""%>><%=currency%></option>
            <%}%>
        </select>


            <input name="<%=srcAmtName%>" type="text" value = <%=formInput%> >

        <select name="<%=dstCucyName%>">
            <% for (String currency : currencies) { %>
              <option value="<%=currency%>" <%=currency.equals(Curr2)?"selected":""%>><%=currency%></option>
            <%}%>
        </select>


            <input name="<%=dstAmtName%>" type="text" disabled="disabled" value = <%=formOutput%>>

            <br>


            <input name="submitbutton" type="submit" value="Convert" name="Convert"/>
            <input name="resetbutton" type="reset" value="Reset"/>  




       <form/> 
       <div/>
    </body>
</html>

One thing I'm really not understanding is that I'm not supposed to "hard code" the form controls in the html so that is why these "SRC_AMT_KEY" keys were provided. I'm just not sure exactly how to implement them. I tried my best but I don't understand this part entirely. Are the keys supposed to replace variables like "Curr1" and "Curr2"? This is how the application worked before but we are updating it now so that nothing is hard coded. I would really appreciate any help in understanding this project. I've been stuck on it for a couple days now and I will continue to update the code if I make any progress. Thank you!

我真的不明白的一件事是,我不应该在 html 中“硬编码”表单控件,这就是提供这些“SRC_AMT_KEY”键的原因。我只是不确定如何实现它们。我尽力了,但我不完全理解这部分。键是否应该替换像“Curr1”和“Curr2”这样的变量?这是应用程序以前的工作方式,但我们现在正在更新它,以便没有硬编码。我真的很感激在理解这个项目方面的任何帮助。我已经坚持了几天,如果我取得任何进展,我将继续更新代码。谢谢!

Here are also the contents of the fxCalc.prp file:

这里也是 fxCalc.prp 文件的内容:

dst.amt=dstAmt
dst.cucy=dstCucy
fx.rates.file.dlmtr=,
fx.rates.file.name=/WEB-INF/fxRates.csv
src.amt=srcAmt
src.cucy=srcCucy

The fxRates.csv file also contains these codes:

fxRates.csv 文件还包含以下代码:

CAD,EUR,GBP,USD
1.0,0.624514066,0.588714763,0.810307
1.601244959,1.0,0.942676548,1.2975
1.698615463,1.060809248,1.0,1.3764
1.234100162,0.772200772,.726532984,1.0

回答by Chandra Shekhar Goka

In FxDataModel.Java class you declared the properties reference as private Properties fxProps;

在 FxDataModel.Java 类中,您将属性引用声明为 private Properties fxProps;

but you didn't assign Properties Object. By default it assigned with null, on null value you are calling fxProps.getProperty( FX_RATES_FILE_DLMTR_KEY );. So then at run-time the JVM throws NullPointerException.

但你没有分配属性对象。默认情况下,它分配了null, 在您调用的空值上fxProps.getProperty( FX_RATES_FILE_DLMTR_KEY );。因此,在运行时 JVM 会抛出 NullPointerException。

Solution:

解决方案:

private Properties fxProps = new Properties();
fxProps .setProperty(FX_RATES_FILE_DLMTR_KEY,"fx.rates.file.dlmtr");
private String delimiter = fxProps.getProperty( FX_RATES_FILE_DLMTR_KEY );