【问题标题】:Objects in Java Reference or ValueJava 引用或值中的对象
【发布时间】:2009-10-14 12:04:47
【问题描述】:

只是为了我的理解。下面的示例代码是否真的改变了 IntHashtable 中我的汽车对象的颜色,或者第一行是否创建了汽车的另一个​​实例 对象,第二行后包含 color = red?

谢谢,
亨里克

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

编辑:
还有比这更好的方法吗?

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

【问题讨论】:

    标签: java object


    【解决方案1】:

    它将属性setColor 更改为red 指向的内容。所以你的哈希表中的对象被改变了。

    一个小演示:

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

    将产生:

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

    如您所见,使用generics 时也不需要强制转换。

    【讨论】:

    • 谢谢!它是 J2ME,所以没有泛型支持 :(
    • 啊 J2ME,我明白了(不适合 Android?:))。当然,不客气!
    【解决方案2】:

    非原始类型的变量是引用,因此在您的示例中,myCar 是对哈希表中Car 对象的引用。当您通过引用 myCar 更改成员变量 setColor 的值时,您正在更改哈希表中 Car 对象的内容。

    如果myIntHashTable 是普通的java.util.Hashtablejava.util.HashMap,则不会复制您的Car 对象。

    一些补充说明:

    • 使用HashMap 而不是HashtableHashtable 是一个遗留集合类,它(几乎在所有用途)已被 HashMap 取代。
    • 你的类Car 显然有一个名为setColor 的公共成员变量,这有点奇怪。不要公开成员变量,也不要给他们起奇怪的名字,比如setColor

    关于最后一点:在你的类Car中放一个私有成员变量color,并实现一个setColor方法:

    public class Car {
        private Color color;
    
        public void setColor(Color color) {
            this.color = color;
        }
    
        // ...
    }
    
    // Somewhere else:
    myCar.setColor(Color.RED);
    

    【讨论】:

    • 但是随着 vom C++ 和 C# 的到来,在 java 中没有办法真正手动更改引用,不是吗?
    • 你到底是什么意思?您可以为不同的对象创建参考点;只需将其他内容分配给myCar,例如myCar = new Car();
    【解决方案3】:

    它实际上改变了哈希表中的值。请注意,如果您正在做的事情改变了关键对象的 hashCode 或等于返回值,那么您可能会受到伤害。另一方面,仅更改哈希表的值通常是可以的。

    【讨论】:

      【解决方案4】:

      我对这个问题的股票推荐是阅读以下两篇文章:

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

      还有比这更好的方法吗?

      你觉得哪个更易读?我认为第一个是。

      【讨论】:

        【解决方案5】:

        它改变了存储在表中的Car 实例的'Color' 属性的值; 创建新值。

        您没有显示myIntHashTable 的类型。请注意,java.util.Map 通常比传统的 java.util.Hashtable 更受欢迎。后者进行锁定。

        另外,您是否按连续整数值索引这些汽车?如果是这样,您可能需要某种形式的List

        你可能想要这样的东西:

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

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

        无泛型,只需自己进行转换:

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

        当您不确定两个对象是否是同一个对象时,您可以随时将对象引用与== 进行比较:

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

        【讨论】:

          【解决方案6】:

          回答你的第二个问题,如果你能够定义哈希表是什么:

          Hashtable<Integer, Car> myHashTable = new Hashtable<Integer, Car>();
          
          myHashTable.add(1, theCar);
          
          myHashTable.get(1).setColor(red);
          

          【讨论】:

          • 您的示例是错误的,因为您不能将诸如int 之类的原始类型用于泛型类型。请改用Integer,即Hashtable&lt;Integer, Car&gt;
          猜你喜欢
          • 1970-01-01
          • 2017-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多