开发者

Objects in Java Reference or Value

just for my understanding. Does my example code below actually changes the the color of my Car Object in the IntHashtable or does the first line creates another instance of the car object, which contains color = red after the second line?

thanks,

Henrik

Car myCar = (Car)myIntHashTable开发者_开发问答.get(index);   
myCar.setColor = red;

Edit:

Is there a better way than this?

((Car)myIntHashTable.get(index)).setColor = red;


It changes the attribute setColor into what red points to. So the object in your hash table gets changed.

A little demo:

import java.util.*;

public class Main {

  public static void main(String[] args) {
    List<Foo> foos = new ArrayList<Foo>();
    foos.add(new Foo());
    foos.add(new Foo());
    foos.add(new Foo());
    System.out.println("foos="+foos);
    foos.get(1).n = 1;
    System.out.println("foos="+foos);
  }

  static class Foo {
    int n = 0;
    @Override 
    public String toString() {
      return String.valueOf(n);
    }
  }
}

will produce:

foos=[0, 0, 0]
foos=[0, 1, 0]

As you can see, there also is no need for casting when using generics.


Variables of non-primitive types are references, so in your example myCar is a reference to the Car object in the hash table. When you change the value of the member variable setColor through the reference myCar, you are changing the contents of the Car object that's in the hash table.

If myIntHashTable is a normal java.util.Hashtable or java.util.HashMap, no copy of your Car object is made.

Some additional notes:

  • Use HashMap instead of Hashtable. Hashtable is a legacy collection class, which has (for almost all purposes) been replaced by HashMap.
  • It's a bit strange that your class Car apparently has a public member variable called setColor. Don't make member variables public, and don't give them strange names such as setColor.

About the last point: Put a private member variable color in your class Car and implement a setColor method:

public class Car {
    private Color color;

    public void setColor(Color color) {
        this.color = color;
    }

    // ...
}

// Somewhere else:
myCar.setColor(Color.RED);


It actually changes the value in the hash table. Note that if what you're doing changes a key object's hashCode or equals return values, you could be in a world of hurt. Changing just the hash table's value, on the other hand, is usually ok.


My stock recommendation for this question is to read the following two articles:

  1. Cup Size -- a story about variables
  2. Pass-by-Value Please (Cup Size continued)

Is there a better way than this?

Which do you find more readable? I think the first is.


It changes the value of the 'Color' property of the Car instance stored in the table; a new value is not created.

You don't show a type for myIntHashTable. Note that java.util.Map is typically preferred over the legacy java.util.Hashtable. The latter does locking.

Also, are you indexing these cars by consecutive integral values? If so, you might want some form of List.

You probably want something like this:

final Map<Integer, Car> cars = new HashMap<Integer, Car>();
final Car someCar = new Car();
cars.put(1, someCar);
final Car carInTable = cars.get(1). // refers to same object as someCar
carInTable.setColor(red);

A List implementation is similar:

final List<Car> cars = new ArrayList<Car>();
final Car someCar = new Car();
cars.add(someCar);
final Car carInTable = cars.get(1). // refers to same object as someCar
carInTable.setColor(red);

Sans Generics, just do the casting yourself:

final Map cars = new HashMap();
final Car someCar = new Car();
cars.put(1, someCar);
final Car carInTable = (Car) cars.get(1). // refers to same object as someCar
carInTable.setColor(red);

final List cars = new ArrayList();
final Car someCar = new Car();
cars.add(someCar);
final Car carInTable = (Car) cars.get(1). // refers to same object as someCar
carInTable.setColor(red);

You can always compare object references with == when in doubt about whether two objects are the same object:

System.println.out("someCar and carInTable are " + ((someCar == carInTable) ? "" : "not ") + "the same object");


To answer your second question, if you are able to define what the hashtable is:

Hashtable<Integer, Car> myHashTable = new Hashtable<Integer, Car>();

myHashTable.add(1, theCar);

myHashTable.get(1).setColor(red);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜