0

私は今日、コードの一部でファイルからデータを読み取り、それらをプロパティとしてオブジェクトに追加するのに苦労していました(この手間をかけずにファイル内のオブジェクトを追加/読み取る方法を知っていますが、この方法でやりたかったのです)以下のように:

ファイルは次のようになります。

111,john,23.1
222,jack,22.5
234,adam,12.8

私は以下を使用してこのファイルを読み込もうとしていました:

public ArrayList<Staff> LoadAllStaffs(){
    ArrayList<Staff> staffs = new ArrayList<Staff>();
    File file = new File(stafffile);
    Staff tmpstaff = new Staff();
    try {
        BufferedReader inputfile = new BufferedReader(new FileReader(stafffile));
        String tmp;
        while((tmp = inputfile.readLine()) != null){
            StringTokenizer st = new StringTokenizer(tmp , ",");
            tmpstaff.setID(Integer.valueOf(st.nextToken()));
            tmpstaff.setFirstName(st.nextToken());
            tmpstaff.setSalary(Double.valueOf(st.nextToken()));
            staffs.add(tmpstaff);
            }
        } 
    catch (IOException e) {
    }
    return staffs;
}

println返されたから示されるこの出力を使用してArrayList

234,adam,12.8
234,adam,12.8
234,adam,12.8

whileループの内側を移動したStaff tmpstaff = new Staff();ところ、それがどうあるべきかがわかります。

なぜこれが起こっているのですか?私は-ここでも-ループの内側または外側で変数(ここではそのオブジェクト)を定義しても違いがないことを読みました。

4

4 に答える 4

5

Staffループ内に新しいインスタンスを作成するのではなく、すべての反復で同じインスタンスを再利用します。したがって、値を上書きして同じオブジェクトを追加します。

動く

Staff tmpstaff = new Staff();

ループ内の最初の行に。

更新:Vashのコメントに対処するために、ここでの問題は、3つのオブジェクトを格納する場合は、そのような3つのオブジェクトを作成する必要があると説明できることです。参照(変数)を再利用でき、tmpstaff定義されている場所では重要ではありません(参照がすべて同じスコープ内にある限り)。ただし、3つのオブジェクト、つまり3つのnewコマンドを作成する必要があります。

更新2:物事を簡単にするために、テキストは次のI read -even here- that defining variables (well, here its an Object ) inside or outside loops doesn't make any difference.ことを意味します

File file = new File(stafffile);
Staff tmpstaff = null; // or simpler, Staff tmpstaff;
try {
   ...
   while((tmp = inputfile.readLine()) != null){
     tmpstaff = new Staff();
     ...

   while((tmp = inputfile.readLine()) != null){
     Staff tmpstaff = new Staff();
     ...

同等です。

于 2012-12-15T22:15:06.847 に答える
2

オペレーターnewは、インスタンスと呼ばれる「オブジェクトの作成」を担当します。したがって、ループの外側で彼を作成すると、インスタンスが 1 つだけになり、すべてのループ実行を変更できます。ループ内でそのオブジェクトを作成すると、実行ごとに個別のインスタンスが作成されます。

于 2012-12-15T22:20:01.670 に答える
2

Java はオブジェクトの参照によって動作します。Staff() オブジェクトを 1 つしか作成していないため、参照も 1 つしかありません。したがって、while ループでは、オブジェクトの属性だけを変更し、同じ参照をリストに 3 回追加します。

ループ外で変数を定義できますが、ループ内で新しいオブジェクトをインスタンス化する必要があるため、次のようになります。

Staff tmpStaff
while((tmp = inputfile.readLine()) != null){
tmpStaff = new Staff();
[additional Code here]
}
于 2012-12-15T22:20:03.590 に答える
2

ループの各パスで新しい譜表を作成する場合は、使用する前にループ内で作成する必要があります。

あなたが行ったようにループの外で実行すると、確かに新しいスタッフが作成されますが、同じものが毎回使用され続けます。

新しいオブジェクトは、new キーワードが使用された場合にのみ作成されます。

于 2012-12-15T22:20:51.837 に答える