代码之家  ›  专栏  ›  技术社区  ›  Andrei Ciobanu

为什么原语的包装类没有setter?

  •  4
  • Andrei Ciobanu  · 技术社区  · 14 年前

    我这样问是因为这样的功能简化了微积分,使Java语言更加灵活。

    让我举几个例子。

    1) 我们举下面的例子:

    Integer x = new Integer(5);
    x++;
    

    前面的幕后代码正在执行自动装箱。比如:

    int x_tmp = x.intValue();
    x_tmp++;
    x = new Integer(x_tmp); // Yes that's a new memory allocation
    

    由于这个问题,在包装器上执行微积分比在普通基元类型上执行微积分要慢。有了setter,就可以更容易地增加内部值,而无需在堆上分配另一个对象。

    2)另一个困扰我的问题是java不可能编写一个交换函数,就像我可以用C(使用指针)或C++(指针或引用)来做的那样。

    void swap(Integer x, Integer y) 我无法访问内部值,因为我不可能交换这些值。

    我的一个朋友建议我应该从更大的角度来考虑,从并发性和类型不变性的角度来考虑。

    你对此有什么解释吗? 谢谢!

    4 回复  |  直到 12 年前
        1
  •  4
  •   Jon Skeet    14 年前

    1) 对于setter,包装器类型是可变的。不变性在很多方面都是好事。。。线程、代码的一般可理解性等。我个人认为 Calendar Date 例如,是可变的。

    事实上,你的扩张 x++; 不太正确-它使用 Integer.valueOf 总是创造新的价值。例如:

    Integer x = 5;
    x++;
    Integer y = 5;
    y++;
    
    // This prints true    
    System.out.println(x == y); // Compare references
    

    Integer 值是这样缓存的(规范定义了哪些值 必须 这样做,但是如果JRE希望这样做,允许更大的范围)。。。但这确实意味着它不会总是创建一个新对象。

    2) 是的,Java没有pass-by-reference。坦白说,我很少觉得这是个问题。您真的需要多久交换一次变量的值?

        2
  •  6
  •   Christian    14 年前

    集合和哈希表需要哈希值始终相同。

        3
  •  4
  •   Andreas Dolk    14 年前

    在-128到127范围内缓存整数需要不可变的整数。考虑以下代码:

    Integer id = Integer.valueOf(1);  // a new Integer, cached in Integer class
    
    // and somewhere else
    
    Integer key = Integer.valueOf(1);  // returns the cached value
    

    现在 整数是可变的,有一个setter,有人做了

    key.setValue(2);  // not legal Java code, just for demonstration
    

    id 而且,令很多人惊讶的是:

    Integer one = Integer.valueOf(1);
    if (one != 1)
       System.out.println("Surprise! I know, you expected `1`, but ...");