Object References - Why Is It Referring to the Wrong Object?

时间:2015-12-14 00:16:44

标签: java oop io

I am attempting to read a file where each line is to be used to created an object I've called Food. Each line is also comma-delimited, so I am using an instance of the StringTokenizer class to parse through the data. Here's a peak at the contents of the file I am using:

Aldi's Distribution Center,Gertrude ,Hagge,90411,3158,fruit & grapefruit,decay,15,cases,8422,40914

Campbell Soup Company,Roch,Carter,90410,8583,soup & tomato,short-dated,2,pallets,,

Kikkoman Foods,Arnold,Brown,90328,5045,marinade - herb  garlic,damaged,4,cases,,

The Food class has several instance variables, one of them being another class that I've defined called Name. Name has only two instance variables, one string for a first name and another for a last name. For some reason, I originally thought it'd be useful to create a function in my Name class that performed the following:

    public Name copy(){ 
        Name nameCopy = new Name(this.first, this.last); 
        return nameCopy; 
    } 

Then, as I was creating the Food class, I created the following get method for Name:

    public Name getContact(){
        return contact.copy();
    }

My default and overloaded constructors for Food are the following:

public Food(){
    this("Google", new Name(), "091024", "8502", "Jiffy peanut butter", "other", 4399, "cases"); 
}

public Food(String corpName, Name contact, String date, String productCode, String description, String reason, int number, String cop){
    this.corpName = corpName;
    this.contact = contact;
    this.date = date;
    this.productCode = productCode;
    this.description = description;
    this.reason = reason;
    this.number = number;
    this.cop = cop;
}

So, I have my default constructor of Name part of the default constructor of Food.

Here's the real meat and potatoes of what I'm getting at. The code I use to parse through the data is the following:

    try{
        Scanner scan = new Scanner (new File("foodBankInput.txt"));
        while(scan.hasNextLine()){
            String stringRead = scan.nextLine();
            StringTokenizer tokens = new StringTokenizer(stringRead,",");
            Food temp = new Food();
            temp.setCorpName(tokens.nextToken());
            temp.getContact().setLast(tokens.nextToken());
            temp.getContact().setFirst(tokens.nextToken());
            temp.setDate(tokens.nextToken());
            temp.setProductCode(tokens.nextToken());
            temp.setDescription(tokens.nextToken());
            temp.setReason(tokens.nextToken());
            String numberString = tokens.nextToken();
            int number = Integer.parseInt(numberString);
            temp.setNumber(number);
            temp.setCoP(tokens.nextToken());
            list.insert((Food)temp);
            System.out.println(temp.toString() + "\n");
        }
        scan.close(); 
    }

list is an instance of a class that I've created called FoodArrayList which pretty much performs the same operations as the ArrayList class. My problem now is that if I keep getContact() as it is, each instance of Food in my array uses the default constructor of Name. Why does it do this? I understand that it will create multiple copies/instances of a Name object each time copy() is used. However, shouldn't each copy of the Name object have the same contents (first and last name) as the previous one, based on the way that I've defined copy()?

I understand that if I adjust my getContact() method to the following, my code will work as I want it to:

    public Name getContact(){ 
       return contact; 
    } 

However, I still don't totally understand why this is the solution. Any input on this would be appreciated.

1 个答案:

答案 0 :(得分:4)

这是因为您使用默认构造函数Food()创建 temp ,它还为从默认构造函数Name()创建的对象分配联系人。

接下来,您尝试使用setter覆盖值,但是当您调用getContact()时,它会返回副本。您没有更改与 temp 关联的对象!

修改了getContact()之后,您开始返回与 temp 实例关联的实例。