简体   繁体   English

Java参考或值中的对象

[英]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? 下面的示例代码是否实际上会更改IntHashtable中我的Car对象的颜色,或者第一行是否创建了car对象的另一个实例,在第二行之后包含color = red?

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. 它将属性setColor更改为red指向的内容。 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. 非基本类型的变量是引用,因此在您的示例中, myCar是对哈希表中Car对象的引用 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. 通过引用myCar更改成员变量setColor的值时,将更改哈希表中Car对象的内容。

If myIntHashTable is a normal java.util.Hashtable or java.util.HashMap , no copy of your Car object is made. 如果myIntHashTable是普通的java.util.Hashtablejava.util.HashMap ,则不会复制您的Car对象。

Some additional notes: 一些附加说明:

  • Use HashMap instead of Hashtable . 使用HashMap代替Hashtable Hashtable is a legacy collection class, which has (for almost all purposes) been replaced by HashMap . Hashtable是一个遗留集合类,它(几乎出于所有目的)已被HashMap取代。
  • It's a bit strange that your class Car apparently has a public member variable called setColor . 奇怪的是,您的Car类显然具有名为setColor的公共成员变量。 Don't make member variables public, and don't give them strange names such as setColor . 不要公开成员变量,也不要给它们奇怪的名称,例如setColor

About the last point: Put a private member variable color in your class Car and implement a setColor method: 关于最后一点:将私有成员变量color放入类Car并实现setColor方法:

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. 请注意,如果您正在执行的操作更改了键对象的hashCode或等于返回值,那么您可能会遭受重创。 Changing just the hash table's value, on the other hand, is usually ok. 另一方面,仅更改哈希表的值通常是可以的。

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);

It changes the value of the 'Color' property of the Car instance stored in the table; 它更改存储在表中的Car实例的'Color'属性的值; a new value is not created. 不会创建新值。

You don't show a type for myIntHashTable . 您不会显示myIntHashTable的类型。 Note that java.util.Map is typically preferred over the legacy java.util.Hashtable. 请注意,相对于旧版java.util.Hashtable,通常首选java.util.Map。 The latter does locking. 后者会锁定。

Also, are you indexing these cars by consecutive integral values? 另外,您是否通过连续的整数值索引这些汽车? If so, you might want some form of List . 如果是这样,您可能需要某种形式的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: List实现类似于:

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: Sans Generics,自己动手做:

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");

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. 我认为第一个是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM