【问题标题】:Why wrapper class in Java doesn't behave like a reference type?为什么 Java 中的包装类不像引用类型?
【发布时间】:2017-11-28 12:09:01
【问题描述】:

我很难理解为什么 Java 中的包装器类的行为不像引用类型。 示例:

Integer one = 10;
Integer two = one;
one = 20;
System.out.println(one);
System.out.println(two);

输出将是:

20

10

我认为two 将是 20,就像在我创建自己的类的示例中一样:

class OwnInteger {
        private int integer;

        public OwnInteger(int integer) {
            this.integer = integer;
        }

        public int getInteger() {
            return integer;
        }

        public void setInteger(int integer) {
            this.integer = integer;
        }
    }

    OwnInteger one = new OwnInteger(10);
    OwnInteger two = one;
    one.setInteger(20);
    System.out.println(one.getInteger());
    System.out.println(two.getInteger());

那么问题来了,Integer 包装器类是特殊的吗?为什么它的行为与我在示例中显示的一样?

【问题讨论】:

  • one = 20;one.setInteger(20); 有很大的区别,和包装类无关。第一个 sn-p 的 one = 20; 将等效于第二个 sn-p 中的 one = new OwnInteger(20);
  • 这些类的行为与引用类型完全一样,可能是因为它们引用类型。当您将一个引用指向不同的对象时,您不会更改另一个指针。指针是独立的。它只是通过指向同一 object 的任何指针可见的对 object 的更改。请记住,正如 JLS 所说,Java“引用......是指针”。

标签: java class types reference wrapper


【解决方案1】:

这正是引用类型的行为。在您的示例中,two 在分配后引用与one 相同的对象。但是,重新分配 one 一个新对象对 two 没有影响,这是您看到的行为。

例如,您也会看到与其他参考对象相同的行为

StringBuilder one = new StringBuilder("10");
StringBuilder two = one;
one = new StringBuilder("20");
// two still references StringBuilder with "10"

为了让引用类在改变一个对象同时改变另一个对象时表现出行为,该类需要是可变的,就像您代码中的OwnInteger 类, 代码需要更改对象,而不是重新分配它。包装类(例如 Integer)是不可变的,因此您不会遇到这种行为。

【讨论】:

    【解决方案2】:

    我以为两个会是 20...

    不,当你这样做时

    Integer two = one;
    one = 20;
    

    您实际上是在为变量 one 分配一个新对象,而变量 two 将不会随着这些更改而更新...

    到你的班级 OwnInteger

    OwnInteger one = new OwnInteger(10);
    OwnInteger two = one;
    one.setInteger(20);
    

    他们会按照您的预期行事,因为 onetwo 指向同一个引用。

    代码A 将等同于

    OwnInteger one = new OwnInteger(10);
    OwnInteger two = one;
    one = new OwnInteger(20); //one.setInteger(20);
    

    【讨论】:

    • "一和二指向同一个引用.." 错了,它们指向同一个对象
    【解决方案3】:
    one = 20;
    

    使用“拳击”,实际上相当于这样:

    one = Integer.valueOf(20);
    

    在您的情况下,valueOf 方法创建一个新对象并返回该新创建对象的引用,因为以前不存在于缓存中。

    对于您自己的类onetwo,两个引用变量都指向同一个对象。

    【讨论】:

    • 即使没有自动装箱也会发生同样的事情,这不是 OP 观察的原因。
    【解决方案4】:

    到目前为止,其他答案都至少部分错误。您看到的效果与自动装箱或可变性无关。像第一步一样更改指针和像第二步那样通过指针更改对象是完全不同的事情。更改指针将其指向不同的对象。您没有更改两个指针,因此它们指向不同的对象。无论可变性或装箱转换如何,都会发生这种情况。

    【讨论】:

      猜你喜欢
      • 2021-08-18
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      • 2011-04-04
      • 2020-08-28
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      相关资源
      最近更新 更多