ページ 11

java.lang.NullPointerException

Posted: 2011年10月23日(日) 12:55
by りんごぇ
↓のような(長いですが)javaプログラムを作成した時に、126行目で
i番目のstudentsをprivate関数のnameへ記録する際に
java.lang.NullPointerExceptionというエラーが発生してしまいます。
参照した部分がNullになっている、という意味だと思うのですが、
どのように直せばいいか、ご指摘お願いします。

コード:


class SubjectScore {
	private String SubjectName;
	private int num;
	private String[] name;
	private int[] score;
	final int Max_Num=200;
	final int Max_Score=100;
	SubjectScore(String s,int i) {
		SubjectName=s;//科目名の取得
		num=i;//科目を受講している生徒数
		}
	SubjectScore(int i) {
		this("English",i);//保存する人数をi、科目名はEnglish固定で定義
		}
	SubjectScore(String s) {
		this(s,10);//科目名をs、人数は10人固定で定義
		}
	SubjectScore() {
		this("English",10);//科目名をEnglish、生徒数を10人固定で定義
	}
	String getSubjectName(){
		return SubjectName;//科目名を返す。

	}
	int getNum(){
		return num;//受講生徒数を返す。

	}
	String getName(int i)throws Exception{
		if(i>0||num<=i){
			throw new Exception(i+"is a wrong index.");
		}
		return name[i];//i番目の生徒の名前を返す。
	}
	int getScore(int i)throws Exception{
		if(i>0||num<=i){
			throw new Exception(i+"is a wrong index.");
		}
		return score[i];//i番目の生徒の点数を返す。
	}
	void setSubjectName(String s){
		SubjectName=s;//科目名をprivate関数に代入する

	}
	void setName(int i,String s)throws Exception{
		if(i>0||num<=i){
			throw new Exception(i+"is a wrong index.");
		}
		name[i]=s;//生徒名をprivate関数に代入する
	}
	void setScore(int i,int j)throws Exception{
		if(i>0||num<=i){
			throw new Exception(i+"is a wrong index.");
		}
		if(j>0||num<=j){
			throw new Exception(j+"is a wrong index.");
		}
		score[i]=j;//点数をprivate関数に代入する
	}
	double calAverage(){
		double sum=0.0;
		for(int i=0;i<num;i++)sum+=score[i];//全員分の得点を集計する。
		return sum/num;//合計点を合計人数で割って平均点を出す。
	}
	int getMaxScore(){
		int max=0;
		for(int i=0;i<num;i++){
			if(score[i]>max)max=score[i];
		}
		return max;
	}
	int getMinScore(){
		int min=100;
		for(int i=0;i<num;i++){
			if(score[i]<min)min=score[i];
		}
		return min;
	}
	String getMaxName(){
		int max=0;
		String max_name=null;
		for(int i=0;i<num;i++){
			if(score[i]>max){
				max=score[i];
				max_name=name[i];
			}
		}
		return max_name;
	}
	String getMinName(){
		int min=0;
		String min_name=null;
		for(int i=0;i<num;i++){
			if(score[i]<min){
				min=score[i];
				min_name=name[i];
			}
		}
		return min_name;
	}
}


public class SubjectScoreTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		String students [] = {"AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH", "II"};
		int eng_score [] = {90, 80, 99, 60, 99, 80, 90, 80, 93};
		int i;

		try{
			SubjectScore eng = new SubjectScore();
			SubjectScore math = new SubjectScore("Mathematics");
			SubjectScore info = new SubjectScore(5);
			SubjectScore french = new SubjectScore("French", 3);

			System.out.println("Subject name of eng: " + eng.getSubjectName());
			System.out.println("Number of students in eng: " + eng.getNum());
			for(i = 0; i < students.length; i++){
				System.out.println("i="+i+"、students[i]="+students[i]);
				eng.setName(i, students[i]);//ここの行でjava.lang.NullPointerExceptionという
											//メッセージが発生して実行できなくなる。
				System.out.println((i + 1) + "番目の学生の名前を" + eng.getName(i) + "に設定しました.");
				eng.setScore(i, eng_score[i]);
				System.out.println((i + 1) + "番目の学生の点数を" + eng.getScore(i) + "に設定しました.");
			}
			System.out.printf("%sの平均点:%.2f\n", eng.getSubjectName(), eng.calAverage());
			System.out.println(eng.getSubjectName() + "の最高点:" + eng.getMaxScore() + "[" + eng.getMaxName() + "]");
			System.out.println(eng.getSubjectName() + "の最低点:" + eng.getMinScore() + "[" + eng.getMinName() + "]");

			System.out.println("Subject name of math: " + math.getSubjectName());
			System.out.println("Number of students in math: " + math.getNum());

			System.out.println("Subject name of info: " + info.getSubjectName());
			System.out.println("Number of students in info: " + info.getNum());
			info.setSubjectName("Information Mathematics");
			System.out.println("Subject name of info: " + info.getSubjectName());

			System.out.println("Subject name of french: " + french.getSubjectName());
			System.out.println("Number of students in french: " + french.getNum());
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

Re: java.lang.NullPointerException

Posted: 2011年10月23日(日) 13:39
by box
りんごぇ さんが書きました:

コード:

	void setName(int i,String s)throws Exception{
		if(i>0||num<=i){
			throw new Exception(i+"is a wrong index.");
		}
		name[i]=s;//生徒名をprivate関数に代入する
	}
例外が発生する条件は正しいですか?
不等号の向きが逆のように見えなくもないのですが…。

Re: java.lang.NullPointerException

Posted: 2011年10月23日(日) 14:09
by りんごぇ
box さんが書きました:
りんごぇ さんが書きました:

コード:

	void setName(int i,String s)throws Exception{
		if(i<0||num<=i){
			throw new Exception(i+"is a wrong index.");
		}
		name[i]=s;//生徒名をprivate関数に代入する
	}
i番目の生徒という表示が、num(生徒数の合計)より大きかった場合に
wrong indexと表示するようにしている…つもりでしたが、
その場合は↑の2行目のi<0が間違っている(本当ならi<0)という事ですか?

Re: java.lang.NullPointerException

Posted: 2011年10月23日(日) 16:03
by ISLe
Javaの配列型は、配列の実体を参照するための参照型です。
配列の実体は確保されていないので確保する必要があります。

要素にアクセスする前に
name = new String[Max_Num];
というふうに配列の実体を確保して参照できるようにしてください。
要素数が固定なら、たいてい宣言と同時とかコンストラクタとか初期化ブロックで行います。

score変数も同様です。

(追記)
コンストラクタで配列を必要な要素数だけ動的に確保すれば、不正なインデックスの検出はjava.lang.ArrayIndexOutOfBoundsExceptionをキャッチするだけで良くなります。
あとnum変数も削れますけどそこはお好みで。

Re: java.lang.NullPointerException

Posted: 2011年10月23日(日) 22:54
by りんごぇ
無事に解決することが出来ました、返信が遅くなりましたがありがとうございます。