JAVA/关于空指针异常

Java初学者,用GUI做了一个经典的轮渡系统。我的思路是利用三个排队队列和两个轮渡队列(分别代表两趟船)实现功能。由于每次切界面时会更新对象,输入的内容无法保存,因此需要使用IO流存储信息。大体思路是这样的:
1.先在文件里读取内容到一个6*6的二维数组
2.判断输入内容,如果符合条件的话会存进第1——3行中的某一行;
3.将数组的前1——5行分别存进五个队列里,再进行操作;
4.队列再存进数组里,然后数组再存进文件里
通过这种操作进行数据存储,这里把出问题的软件包给出来:

package src.GroupTest2_1;

import java.time.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.Scanner;
public class Implement implements java.awt.event.ActionListener{
    linkQueue L1=new linkQueue();//五个队列
    linkQueue L2=new linkQueue();
    linkQueue L3=new linkQueue();
    linkQueue L4=new linkQueue();
    linkQueue L5=new linkQueue();
    Scanner reader=new Scanner(System.in);
    Panel P;
    String S,ST;
    String[][] SI1=new String[6][6],SI2=new String[6][6];
    int i=0,j=0,k=0;
    public Implement(Panel P){
        this.P=P;
    }
    public void actionPerformed(ActionEvent event){
        Object O=event.getSource();
        switch (event.getActionCommand()){
            case"进行检票":
                new Panel().TicketChecking();
                P.JF1.setVisible(false);
                break;
            case"时 间 表":
                new Panel().TimeTable();
                P.JF1.setVisible(false);
                break;
            case"车辆状态":
                new Panel().VehicleStatus();
                P.JF1.setVisible(false);
                break;
            case"确 定(检票)":
                File file=new File("D:\\JavaSC-Code\\src\\queue.txt");//读取
                BufferedReader bufferedReader=null;
                try{
                    InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(new File("D:\\JavaSC-Code\\src\\queue.txt")));
                    bufferedReader=new BufferedReader(inputStreamReader);
                    String line=null;
                    int i=0;
                    while((line=bufferedReader.readLine())!=null){
                        if(null!=line){
                            String[] strings=line.split("\\t");
                            for(int k=0;k[i][k]=strings[k];
                            }
                            i++;
                        }
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
                if(Time()==-1||Time()==2){
                    S=P.JTF.getText();
                    if(P.JRB1.isSelected()&&!P.JRB2.isSelected()&&!P.JRB3.isSelected()){//插入
                        for(int i=0;i<6;i++){
                            if(SI1[0][i]==null){
                                SI1[1][i]=S;
                                break;
                            }
                        }
                    }else if(!P.JRB1.isSelected()&&P.JRB2.isSelected()&&!P.JRB3.isSelected()){
                        for(int i=0;i<6;i++){
                            if(SI1[1][i]==null){
                                SI1[1][i]=S;
                                break;
                            }
                        }
                    }else if(!P.JRB1.isSelected()&&!P.JRB2.isSelected()&&P.JRB3.isSelected()){
                        for(int i=0;i<6;i++){
                            if(SI1[2][i]==null){
                                SI1[2][i]=S;
                                break;
                            }
                        }
                    }else
                        System.out.println("error");
                }
                for(int i=0;i<6;i++){
                    if(!SI1[0][i].equals(null))
                        L1.EnQueue(SI1[0][i].substring(0,1),SI1[0][i].substring(1));
                    if(!SI1[1][i].equals(null))
                        L2.EnQueue(SI1[1][i].substring(0,1),SI1[1][i].substring(1));
                    if(!SI1[2][i].equals(null))
                        L3.EnQueue(SI1[2][i].substring(0,1),SI1[2][i].substring(1));
                    if(!SI1[3][i].equals(null))
                        L4.EnQueue(SI1[3][i].substring(0,1),SI1[3][i].substring(1));
                    if(!SI1[4][i].equals(null))
                        L5.EnQueue(SI1[4][i].substring(0,1),SI1[4][i].substring(1));
                }

                EnQueueB();//判断归类
                for(int i=0;i<6;i++){//复存
                    if(!L1.isEmpty())
                        SI2[0][i]=L1.DeQueue().getNumble()+L1.DeQueue().getName();
                    if(!L2.isEmpty())
                        SI2[1][i]=L2.DeQueue().getNumble()+L2.DeQueue().getName();
                    if(!L3.isEmpty())
                        SI2[2][i]=L3.DeQueue().getNumble()+L3.DeQueue().getName();
                    if(!L4.isEmpty())
                        SI2[3][i]=L4.DeQueue().getNumble()+L4.DeQueue().getName();
                    if(!L5.isEmpty())
                        SI2[4][i]=L5.DeQueue().getNumble()+L5.DeQueue().getName();
                }
                FileWriter out=null;
                try{
                    out=new FileWriter("D:\\JavaSC-Code\\src\\queue.txt");
                    for(int i=0;i<6;i++){
                        for(int j=0;j<6;j++){
                            String S=String.valueOf(SI2[i][j]+"");
                            out.write(S+"\t");
                        }
                        out.write("\r\n");
                    }
                    out.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
                new Panel().Menu();
                new Panel().Confirm1();
                P.JF2.setVisible(false);
                break;
            case"确 定(车状)":
                BufferedReader bufferedReader2=null;
                try{
                    InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(new File("D:\\JavaSC-Code\\src\\queue.txt")));
                    bufferedReader2=new BufferedReader(inputStreamReader);
                    String line=null;
                    int i=0;
                    while((line=bufferedReader2.readLine())!=null){
                        if(null!=line){
                            String[] strings=line.split("\\t");
                            for(int k=0;k++){
                                SI1[i][k]=strings[k];
                            }
                            i++;
                        }
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
                for(int i=0;i<6;i++){
                    if(SI1[0][i]!=null)
                        L1.EnQueue(SI1[0][i].substring(0,1),SI1[0][i].substring(1));
                    if(SI1[1][i]!=null)
                        L2.EnQueue(SI1[1][i].substring(0,1),SI1[1][i].substring(1));
                    if(SI1[2][i]!=null)
                        L3.EnQueue(SI1[2][i].substring(0,1),SI1[2][i].substring(1));
                    if(SI1[3][i]!=null)
                        L4.EnQueue(SI1[3][i].substring(0,1),SI1[3][i].substring(1));
                    if(SI1[4][i]!=null)
                        L5.EnQueue(SI1[4][i].substring(0,1),SI1[4][i].substring(1));
                }
                ST=VehicleStatus(S);
                new Panel().Menu();
                new Panel().Confirm2(ST);
                P.JF4.setVisible(false);
                break;
            case"返 回(检票)":
                new Panel().Menu();
                P.JF2.setVisible(false);
                break;
            case"返 回(时表)":
                new Panel().Menu();
                P.JF3.setVisible(false);
                break;
            case"返 回(车状)":
                new Panel().Menu();
                P.JF4.setVisible(false);
                break;
            case"退   出":
                System.exit(1);
        }
    }

    public String VehicleStatus(String S1){
        if(L1.find(S1)||L2.find(S1)||L3.find(S1))
            return S1+"  正在候车区,请耐心等待";
        else if(L4.find(S1)){
            if(Time()==-1||Time()==0)
                return S1+"正在搭乘 湛江湾———特呈岛 8.15 次轮渡";
            else
                return S1+"   已到达特呈岛";
        }else if(L5.find(S1)){
            if(Time()==2||Time()==3)
                return S1+"正在搭乘 湛江湾———特呈岛 13.05 次轮渡";
            else
                return S1+"   已到达特呈岛";
        }else
            return "   未找到车辆信息!";
    }
    public void EnQueueB(){
        if(Time()==-2){
            ;
        }else if(Time()==0){
            if(!L1.isEmpty()&&i<3){
                L4.EnQueue(L1.DeQueue());
                i++;
            }else if(!L2.isEmpty()&&i==3&&j<2){
                L4.EnQueue(L2.DeQueue());
                j++;
            }else if(!L3.isEmpty()&&i==3&&j==2&&k==0){
                L4.EnQueue(L3.DeQueue());
                k++;
            }
        }else if(Time()==2){
            if(L4.size()<6){
                while(i<3&& !L2.isEmpty()&&L4.size()<6)
                    L4.EnQueue(L2.DeQueue());
                while(j<2&&(!L1.isEmpty()||!L3.isEmpty())&&L4.size()<6){
                    if(!L1.isEmpty()&& !L3.isEmpty())
                        L4.EnQueue(L1.DeQueue());
                    else if(!L1.isEmpty()&&L3.isEmpty())
                        L4.EnQueue(L1.DeQueue());
                    else if(L1.isEmpty()&&!L3.isEmpty())
                        L4.EnQueue(L3.DeQueue());
                }while(k==0&&(!L1.isEmpty()||!L2.isEmpty())&&L4.size()<6){
                    if(!L1.isEmpty()&& !L2.isEmpty())
                        L4.EnQueue(L1.DeQueue());
                    else if(!L1.isEmpty()&&L2.isEmpty())
                        L4.EnQueue(L1.DeQueue());
                    else if(L1.isEmpty()&&!L2.isEmpty())
                        L4.EnQueue(L2.DeQueue());
                }
            }
        }
    }
    public int Time(){
        LocalTime time1=LocalTime.now();
        LocalTime time2=LocalTime.of(8,10,0,0);
        LocalTime time3=LocalTime.of(8,15,0,0);
        LocalTime time4=LocalTime.of(8,20,0,0);
        LocalTime time5=LocalTime.of(13,0,0,0);
        LocalTime time6=LocalTime.of(13,05,0,0);
        LocalTime time7=LocalTime.of(13,10,0,0);
        if(time1.isBefore(time2))//未检票
            return -2;
        else if(time1.isAfter(time2)&&time1.isBefore(time3))//检票未发
            return -1;
        else if(time1.isAfter(time3)&&time1.isBefore(time4))//已发未到
            return 0;
        else if(time1.isAfter(time4)&&time1.isBefore(time5))//已到未检
            return 1;
        else if(time1.isAfter(time5)&&time1.isBefore(time6))//检票未发
            return 2;
        else if(time1.isAfter(time6)&&time1.isBefore(time7))//已发未到
            return 3;
        else
            return 4;
    }
}

报错如下:

img


上网查了下,有说是有什么东西没有实例化,还有的说是空指针异常。
虚心若愚(虽然确实很愚),请各位指点迷津,告诉我这个报错该怎么解决。
也欢迎指教这段代码更好的优化方法。

从84行来看 SI1[0][i].substring(0,1) 出现了越界错误,可以得出SI1[0][i]没有两个字符。因此我们要去检查你给SI1[0][i]赋值的地方。也就是44~42行读取文件的地方,,最好打印出来这个二维数组看一下每个值是否正确,。有时候程序上没问题,而BUG是由于测试数据不当引起

这是数组越界异常了,84行。

解决方法如图,可以打断点调试

img

对SI1[0][i]加一个非空判断兼容处理一下

img

原因 : 程序中的变量是 null,就意味着它没有引用指向或者说没有指针。这时,我们对这个变量进行任何操作,都必然会引发空指针异常
空指针异常虽然恼人但好在容易定位,更麻烦的是要弄清楚 null 的含义。比如,客户端给服务端的一个数据是 null,那么其意图到底是给一个空值,还是没提供值呢?再比如,数据库中字段的 NULL 值,是否有特殊的含义呢,针对数据库中的 NULL 值,写 SQL 需要特别注意什么呢?
解决方法:
对于 Integer 的判空,可以使用 Optional.ofNullable 来构造一个 Optional,然后使用 orElse(0) 把 null 替换为默认值再进行 +1 操作。对于 String 和字面量的比较,可以把字面量放在前面,比如"OK".equals(s),这样即使 s 是 null 也不会出现空指针异常;而对于两个可能为 null 的字符串变量的 equals 比较,可以使用 Objects.equals,它会做判空处理。
对于 ConcurrentHashMap,既然其 Key 和 Value 都不支持 null,修复方式就是不要把 null 存进去。HashMap 的 Key 和 Value 可以存入 null,而 ConcurrentHashMap 看似是 HashMap 的线程安全版本,却不支持 null 值的 Key 和 Value,这是容易产生误区的一个地方。
对于类似 fooService.getBarService().bar().equals(“OK”) 的级联调用,需要判空的地方有很多,包括 fooService、getBarService() 方法的返回值,以及 bar 方法返回的字符串。如果使用 if-else 来判空的话可能需要好几行代码,但使用 Optional 的话一行代码就够了。
对于 rightMethod 返回的 List,由于不能确认其是否为 null,所以在调用 size 方法获得列表大小之前,同样可以使用 Optional.ofNullable 包装一下返回值,然后通过.orElse(Collections.emptyList()) 实现在 List 为 null 的时候获得一个空的 List,最后再调用 size 方法。
如有帮助,望采纳

你这只给了部分代码,没法调

String index out of range: -1 这是越界了,应是str.indexOf("+")出错.String 的indexOf方法返回查找字符在字符串中的位置,
但是没找到的话就会返回-1(详细看JDK API文档)。所以当找不到指定字符时救会出错了。
字符串下标从0到str.length(),来个-1自然越界(substring()方法),
最好在处理前做个判断int index = str.indexOf("+")if(index!=-1) op2=Double.parseDouble((str.substring(index,str.length())))else System.out.println("找不到指定字符!")

在这里加一行代码, 打印下:

System.out.println(SI1[0][i]);

img