“Null问题需要解释”的意思是需要对空值问题进行说明。

6

我是一个编程和Java的新手,这是我第一次遇到null,我有点困惑,因为我不知道发生了什么,这种错误是否是编码中的错误?或者其他原因?请用简单的方式解释一下这种情况以及null的整体含义。

public static void main(String[] args) {
    Scanner input = new Scanner (System.in);
    System.out.println("Enter grades size :");

    int Size = input.nextInt();

    String[] y = new String[Size];
    int[] x = new int[Size];

    int Max = 0;
    int Min = x[0];

    String Max_studen = y[0];
    String Min_studen = y[0];

    for (int i = 0 ; i < Size ; i++) {
        System.out.println("Enter student name #" + (i));
        y[i] = input.next();

        System.out.println("Enter student grade : #" + (i));
        x[i] = input.nextInt();

        if (x[i] > Max) {
            Max = x[i];
            Max_studen = y[i];
        } else if (x[i] < Min) {
            Min = x[i];
            Min_studen = y[i];
        }
    }

    System.out.println("Max Student is: " + Max_studen);
    System.out.println("Max grade is: ");
    System.out.println(Max);
    System.out.println("Min Student is: " + Min_studen);
    System.out.println("Min grade is : ");
    System.out.println(Min);
}

输出结果为:

Enter grades size :
2
Enter student name #0
Sam
Enter student grade : #0
85
Enter student name #1
Samy
Enter student grade : #1
95
Max Student is: Samy
Max grade is:
95
Min Student is: null
Min grade is :
0 

2
不好意思,请忽略我之前的评论,但请注意格式化您发布的代码以符合标准。您随意放置大括号、随意缩进和额外空格会导致我(以及可能其他人)误读您的代码,如果您希望得到帮助,这是不希望发生的事情。如果您不知道当前的Java代码格式化标准,请在谷歌上搜索并尝试遵循推荐。 - Hovercraft Full Of Eels
2
请勿将变量名大写。它们应始终以小写字母开头。 - connorp
我已经编辑了,这样更好:D,感谢建议和@connorp,你正确地将变量名大写。这不是一个好主意。 - mostafa magdy
4个回答

9

对于初学者来说,这是一个棘手的问题。让我们一起走过这段代码。

首先重要的是这些行:

String[] y = new String[Size];
int[] x = new int[Size];

这两个数组之间有一个重要的区别。 x 是一个基本类型数组,而 y 是一个对象数组。在 Java 中,基本类型有一个明确定义的默认值(通常为0),因此数组x被初始化为所有单元格都包含0。对于对象来说,没有默认值这样的东西。由于你可以编写自己的类,Java 不知道例如一个Car的好的默认值是什么。因此,对象的默认值是null。暂时定义null作为表示“此单元格为空”的值1。因此,y的每个单元格都包含null作为其值。

现在到了下一条重要的线:

int Min = x[0];
[...]
String Min_studen = y[0];

如前所述,x 的初始值为全部 0。由此得出,Min 现在是 0。我们有一个问题,因为在典型情况下,我们永远不会输入成绩小于 < 0,因此 Min 将永远不会被覆盖。一般来说,如果我们正在寻找某个最大值或最小值,应将它们分别初始化为 Integer.MIN_VALUE(用于最大值)或 Integer.MAX_VALUE(用于最小值)。对于 longfloatdouble,也有类似的常量。这些常量通常可以避免像给定问题这样的问题。由于 Min 永远不会被覆盖,因此 Min_studen 也永远不会被覆盖。y 的初始值为 nullMin_studen 的值也是 null


关于您的代码,有一些注意事项:

  • 变量名应该使用驼峰命名法
  • 数组的[]通常紧跟类型写,不加空格:String[]而非String []
  • {后应该总是换行。
  • 变量名应该有意义和描述性。可以使用studentGradesstudentNames代替xy

有许多网站解释编码规范和样式指南,其中一些在这里这里 2。您可能现在不想看它们,但如果您掌握了Java的基础知识并阅读了它们,请记住它们。


1实际上,null 的意思与我所描述的非常接近,但是推理过程稍微复杂一些,需要读者了解堆和栈内存以及存储位置。

2并不存在“样式指南”。您当然可以定义自己的样式指南。样式指南旨在使代码更易于阅读。请记住,在更改样式指南或其部分时要考虑到这一点。


在输入循环后初始化最小值和最大值,然后创建一个全新的循环来解决问题,这样做很有意义。我应该在问题代码中进行编辑吗? - mostafa magdy
@mostafamagdy请不要从问题中删除问题。但是,您可以通过编辑在问题下放置您的运行代码。 - Turing85

2

null基本上意味着一个变量或对象为空。让我们看一下这个部分:

String[] y = new String[Size];
int[] x = new int[Size];
...
int Min = x [0];
...
String Min_studen = y[0];

此时,x[0]y[0]仍然为空/空元素,因为它们没有被赋值。因此,Min为0,Min_student为空。

跳到MinMin_student被使用的地方:

else if (x[i] < Min) { Min = x[i];
    Min_studen = y [i];
}

由于x[]中没有任何元素被定义为小于0,因此这个if语句将永远不会运行,导致打印时Min_student显示为空。

由于存在几个逻辑错误,因此不存在明确的解决方案,但您需要确保Min不为空,以便程序可以运行。


x[0]既不是“空”也不是null。在Java中,基本类型具有明确定义的默认值。 - Turing85
对于 int 类型,其默认值是零吗? - deezy
请查看此处:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html。 - Turing85
@Turing85 感谢您的见解。我总是为变量分配明确的值,所以我在这里学到了新东西 :) - deezy
1
为本地变量分配值仍然是必要的。只有属性会隐式地被赋予默认值。对我来说,显式地为每个值分配值是良好的编码风格,但在处理例如数组时,了解数组未初始化为随机值(如C / C ++中)或其他内容是很好的。 - Turing85

0

null basically means that the variable hasn't been set to anything yet so it is pointing to a special place in memory called null. You can read more about it here: http://www.programcreek.com/2013/12/what-exactly-is-null-in-java/

I think that your specific issue comes from this code:

if (x[i] > Max) {
    Max = x[i] ;
    Max_studen = y[i];
} else if (x[i] < Min) {
    Min = x[i];
    Min_studen = y[i];
}
//x[i] == Max???

You don't have a case for x[i] == Max. Add that case (possibly by modifying your current case to x[i] >= Max and that should fix the null issue.


我认为空指针错误是由于 Min 引起的,因为 Max 至少有一个初始值为0。然而,你绝对是正确的,Max 没有被正确使用。 - deezy
这不是问题所在。问题在于,Min被(隐式地)初始化为0,并且没有输入小于0的成绩... - Turing85
我替换了它,将其初始化为Max,但仍出现相同的情况。 - mostafa magdy

0
唯一的问题是x [0]和y [0]未初始化。因此,字符串y [0]存储为NULL。x [0]存储为0。
您需要插入额外的条件来使用正确的参数初始化x [0]和y [0]。
检查代码-

if(i == 0){ Max = x [0]; Min = x [0]; }

import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {

    Scanner input = new Scanner (System.in);
    System.out.println("Enter grades size : ");

    int Size = input.nextInt();
    String[] y = new String[Size];
    int[] x = new int[Size];

    // Initialize string to store student names and grades
    // Student[0] for highest grade
    // Student[1] for lowest grade
    String[] Student = new String[2];
    int Max = 0, Min = 0;

    for (int i = 0 ; i < Size ; i++) {
        System.out.println("Enter student (" + (i) + ") name : ");
        y[i] = input.next();
        System.out.println("Enter student (" + (i) + ") grade : ");
        x[i] = input.nextInt();

        // This extra condition was missing in the above code.
        if (i==0) {
            Max = x[0];
            Min = x[0];
        }
        else {
            if (x[i] > Max) {
                Max = x[i] ;
                Student[0] = y[i];
                }

            else if (x[i] < Min) {
                Min = x[i];
                Student[1] = y[i];
                }
            }
        }

    System.out.println("Student with highest grade is: " + Student[0]);
    System.out.println("Max grade is: " + Max);
    System.out.println("Student with lowest grade is: " + Student[1]);
    System.out.println("Min grade is : " + Min);

   }
}

上述程序的输出在此处-
Enter grades size : 
3
Enter student (0) name : 
David
Enter student (0) grade : 
34
Enter student (1) name : 
Sam
Enter student (1) grade : 
42
Enter student (2) name : 
Nancy
Enter student (2) grade : 
25
Student with highest grade is: Sam
Max grade is: 42
Student with lowest grade is: Nancy
Min grade is : 25

希望它有所帮助..


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接