源代码中的Java.lang.nullpointerexception

时间:2013-12-10 16:53:48

标签: java arrays nullpointerexception

好的,这是源代码 -

程序应该能够运行a)如果没有给出参数,请询问带有args的文件名                                   b)如果有args,请将这些args作为方法'parametr'的参数

问题是,程序在文件输入时工作正常,但是如果arg是从CMD或Eclipse给出的。从我的角度来看,代码完全没问题,但IDK ......

//代码块,即创建一个应该提交的输出文件+ //从一个整数到args数组的方法'parametr'

else if (args.length > 0) {

                try {

                    PrintStream ps = new PrintStream("vystup.txt");

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

                        parametr(Integer.parseInt(args[i]));
                    }
                    ps.close();
                }
                catch (Exception g) {

                    g.printStackTrace();
                    System.exit(1);
                }

            }
        }

这指向方法'parametr'&gt;&gt;

//这个方法应该只创建一个名为'pseudoposloupnost'的方法//'Posloupnost'的数组,然后将这个数组复制到一个名为'serazenaPosloupnost'的新数组中 //其余代码并不重要

public static void parametr (int n) { 

                Posloupnost(n); //Another method to count array 'pseudo...'
                serazenaPosloupnost = new int [pseudoposloupnost.length];
                for (int k = 0; k < pseudoposloupnost.length; k++) {
                    serazenaPosloupnost[k] = pseudoposloupnost[k];
                }

                serazeniPosloupnosti(serazenaPosloupnost);

        ps.println(pseudoposloupnost.length + " " + Arrays.toString(pseudoposloupnost));
        ps.println(serazenaPosloupnost.length + " " + Arrays.toString(serazenaPosloupnost));
        ps.println();
        drawPosloupnost();

    }

当我尝试使用给定的参数从CMD运行代码时,Java指向这两个块作为nullpointer异常。

1 个答案:

答案 0 :(得分:2)

我认为你有两个名为ps的变量。其中一个是try块的本地,另一个是(可能)静态类变量。 “可能”因为你没有告诉我们它的声明。

简化:

public class myClass {
    private static PrintStream ps; // we'll refer to this as "ps1"

    public static void parametr(int n) {
         ...
         ps.println("foo");
    }

    public static void myMethod() {
         try {
            PrintStream ps = 
               new PrintStream("x.txt"); // we'll refer to this as "ps2"
            parametr(1);
            ps.close();
         } catch (...) {
         }
    }
}

这是范围的问题。

ps1和ps2是两个不同的变量。

ps1已定义但从未初始化,因此整个程序中的值为null

ps2是围绕它的try块的本地。它没有传递给parametr(),因此parametr()没有看到它。

当parametr()执行ps.println()时,它会查看ps1,它是null,因此是NullPointerException。

解决这个问题的一种方法是不创建ps1,并将ps2传递给parametr():

public class myClass {

    public static void parametr(int n, PrintStream printStream) {
         ...
         printStream.println("foo");
    }

    public static void myMethod() {
         try {
            PrintStream ps = 
               new PrintStream("x.txt"); // we'll refer to this as "ps2"
            parametr(1, ps);
            ps.close();
         } catch (...) {
         }
    }
}

做这种事情通常很好,因为你可以准确地看到你的方法需要和可以接触的变量。

您可以解决此问题的另一种方法是从PrintStream块中的ps = ...语句中删除try,以便分配给类变量。这通常不是一个好主意,因为你从代码的读者那里隐藏了PrintStream的管理。


另一个提示:你调用一个方法posloupnost(n)(我把它的第一个字母改为小写,因为Java程序员更喜欢这个)。我可以猜到:

  • 这种方法浪费时间(因为它的唯一参数是整数,所以方法不能改变它)。
  • 此方法对类变量或全局变量有副作用。

传入受该方法影响的对象几乎总是更好,这样就可以清楚它会产生什么样的效果。即使你打算在屏幕上打印,也最好这样做:

的System.out.println(posloupnost(N));

......或......

posloupnost(n,System.out);