2011-11-01 78 views
4

我有一个叫做examList的HashMap,它存储了学生每门课程的考试成绩。该散列表的关键是courseID,该值是一个数组列表gradeList,其中包含学生在课程中获得的所有成绩。问题如下:Java,我怎样才能避免“可能未被初始化”

// Add a new course exam listing 
// where each course exam can be done a max 5 times 
protected void addExam(String courseID, int grade) { 
    ArrayList<Integer> gradeList; 
    // First check if course is in the list, if not add it 
    if (!examList.containsKey(courseID)) { 
     gradeList = new ArrayList<Integer>(); 
     examList.put(courseID, gradeList); 
     examList.get(gradeList.add(grade)); 
    // If course is already on the list, check if max number of attempts has been reached, if not add new grade 
    } else if (examList.containsKey(courseID)) { 
     if (gradeList.size() <= 5)   // THIS IS WHERE ERROR OCCURES 
      examList.get(gradeList.add(grade)); // HERE ALSO 
     else 
      System.out.println("Maxim number of attempts has been reached."); 
    } 
} 

正如你可以看到我首先定义gradeList,但我还没有初始化。在IF下,我检查学生是否已经完成了此考试。如果他没有为hashmap创建新条目,并且gradeList最终被初始化。在ELSE下(其中,认为有已经初始化了gradeList的元素),我只是添加新的等级。但是,这似乎是问题所在。我无法编译它,因为程序假定gradeList尚未在此初始化。 那么,我该如何解决这个问题?或者我可以通过错误处理来避免它(因为逻辑上,gradeList将始终在ELSE下初始化),对此我知之甚少?

+0

您只在if部分初始化'gradeList'。在其他地方,列表未被初始化,您将收到错误消息。从你的代码片段中,你不清楚'gradeList'是否在你的代码的其他地方被初始化。所以当你说你认为'gradeList'是在你的代码的else-if部分被初始化时,这是如何完成的? – Pieter

回答

6
ArrayList<Integer> gradeList = null; 

在你的情况,这是更好地做一些事情如下:

List<Integer> gradeList = examList.get(courseID); 
if(gradeList == null) { 
    gradeList = new ArrayList<Integer>(); 
    //... do something 
} else { 
    //... do something else 
} 
3

只是在创建变量时初始化gradeList。

ArrayList<Integer> gradeList = new ArrayList<Integer>(); 

或将其设置为null

ArrayList<Integer> gradeList = null; 
+0

好的,但不会在每次调用此方法时都替换列表?我的意思是,如果gradeList的课程已经存在,并且此方法被调用将不会gradeList被新创建并且为空,并且examList.get(gradeList.add(grade))会为此__new__列表添加新的等级而不是旧的? – vedran

+0

如果在方法调用之前列表已经存在,那么您应该将该列表作为方法中的参数传递。 –

2

分配null在其声明:

ArrayList<Integer> gradeList = null; 
1

在声明ArrayList中,简单地写gradeList = null。甚至更好,避免NullPointerException异常,初始化就在现场,像这样的:ArrayList<Integer> gradeList = new ArrayList<Integer>();

+0

好的,但不会在每次调用此方法时都替换列表?我的意思是,如果gradeList的课程已经存在,并且调用此方法将不会新创建emptyList,并且不会创建emptyList,而且可以使用examList.get(gradeList。添加(等级))会将新等级添加到这个新列表中,而不是旧的 – vedran

+1

在您的方法中,gradeList _never_存在于方法的开头,因为您将其声明为局部变量,因此每次都会创建它。如果你希望列表在不同的方法调用之间“生存”(对于同一个对象实例),你应该将gradeList声明为一个属性,而不是局部变量 –

1

如果地图中包含的关键,那么这个键的值就是你的gradeList。只需添加这行else if (examList.containsKey(courseID)) {下:

gradeList = examList.get(courseID); 

注意命名地图examList是相当混乱。为什么不是examMap?还请注意,您可以只使用else {而不是else if (examList.containsKey(courseID)) {:地图包含courseID,否则它不会;没有其他的可能性。 最后,您还必须修复下一行代码,因为它不正确。