【问题标题】:Why don't the wrapper classes for Primitives have a setter?为什么 Primitives 的包装类没有设置器?
【发布时间】:2010-07-21 11:14:15
【问题描述】:

Wrapper 类(如 Integer、Double 等)的内部原始值没有设置器的原因是什么?

我之所以这么问,是因为这种功能会简化微积分,并使 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

由于这个问题,在 Wrapper 上进行演算比在普通原始类型上执行要慢。使用 setter 会更容易增加内部值,而无需在堆上分配另一个对象。

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

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

PS: 我的一个朋友建议我应该考虑更大的图景,并考虑并发性和类型不变性。

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

【问题讨论】:

    标签: java wrapper setter primitive-types immutability


    【解决方案1】:

    通常不使用包装类,除非您需要将它们放入集合中。如果它们是可变的,那么如果在集合内使用并作为哈希表的键就会产生问题。

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

    【讨论】:

    • 我想这应该是程序员的责任而不是语言。但是,嘿,我才刚刚开始以更有条理的方式学习 java。
    • 这不仅仅是包装类:我们之前遇到了一些问题,一些非平凡的类被用作缓存键。这些类是可变的(更糟糕的是,只有默认构造函数)并且在某些时候确实有人(好吧,我)通过更改它们的值来重用一些键。由此产生的错误修复包括使这些关键类不可变......
    【解决方案2】:

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

    事实上,您对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 没有通过引用传递。坦率地说,我很少发现这是一个问题。您真正需要多久交换一次变量的值?

    【讨论】:

    • 这不仅仅是关于交换。在其他情况下,当我以某种方式思考问题时,我意识到我必须重新思考问题。
    • @Andrei:通常我发现这鼓励我将相关值封装在一个单独的类型中,这无论如何都是个好主意。您发现自己想要它的频率有多高?
    • 所以不变性只是为了保护“程序员”和减轻他/她的工作?
    • @Andrei:嗯……像封装、垃圾收集、多态等“只是”让程序员的生活更轻松。以我的经验,它在许多情况下都是一个巨大的优势。
    【解决方案3】:

    缓存 -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
    

    现在 if 整数是可变的并且有一个 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 ...");
    

    【讨论】:

      【解决方案4】:

      在 Java 中,字符串和包装类被设计为不可变的,以避免意外更改数据。您可以查看以下文章以获取更多信息。

      Why Strings and Wrapper classes are immutable in java?

      【讨论】:

        猜你喜欢
        • 2022-11-15
        • 1970-01-01
        • 1970-01-01
        • 2019-06-02
        • 2015-01-04
        • 2012-05-23
        • 2012-11-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多