代码之家  ›  专栏  ›  技术社区  ›  Uri London

Java中对基元类型的引用(如何强制基元数据保持装箱)

  •  4
  • Uri London  · 技术社区  · 6 年前

    我想将对基元类型的引用传递给一个方法,这可能会改变它。

    考虑以下样本:

    public class Main {
    
        Integer x = new Integer(42);
        Integer y = new Integer(42);
    
        public static void main(String[] args) {
            Main main = new Main();
            System.out.println("x Before increment: " + main.x);
    
            // based on some logic, call increment either on x or y
            increment(main.x);
    
            System.out.println("x after increment: " + main.x);
        }
    
        private static void increment(Integer int_ref) {
            ++int_ref;
        }
    }
    

    运行该示例的输出是:

    x Before increment: 42
    x after increment: 42
    

    这意味着int_ref是通过值传递给函数的,而不是通过引用传递给函数的,尽管我的名字很乐观。

    显然,有一些方法可以解决这个特定的示例,但我的实际应用程序要复杂得多,通常人们会认为“指针”或对整数的引用在许多场景中都很有用。

    我曾尝试将对象传递给函数(然后转换为int)和其他各种方法,但没有成功。一个似乎有效的解决方法是定义我自己版本的Integer类:

    private static class IntegerWrapper {
        private int value;
    
        IntegerWrapper(int value) { this.value = value; }
        void plusplus() { ++value; }
        int getValue() { return value; }
    }
    

    编辑:

    Is Java "pass-by-reference" or "pass-by-value"? ,因为我的问题不是理论性的,因为我只是寻求一个解决方案。从理论上讲,所有语言中的所有方法调用都是按值传递的:它们要么传递实际值,要么传递对值的引用。

    因此,我要重新表述我的问题:在java中,我无法传递对整数的引用,解决这个问题的常见范例是什么。上面提到的整数说话者是一个已知的范例吗?库中是否已经存在类似的类(可能是MutableInt)?长度为1的数组可能是一种常见做法,并且具有一些性能优势?我是唯一一个因为他可以存储对任何类型对象的引用而感到恼火的人,但基本类型除外?

    1 回复  |  直到 6 年前
        1
  •  6
  •   Oleg Cherednik    6 年前

    Integer 正如你可能注意到的,它是不可变的。

    private static class IntegerWrapper 这是正确的。使用大小为1的数组也是正确的,但实际上我从未见过在这种情况下使用数组。所以使用 IntegerWrapper.

    org.apache.commons.lang3.mutable.MutableInt

    在您的示例中,您还可以提供 Main 静态方法的实例:

    public class Main {
    
        private int x = 42;
    
        public static void main(String[] args) {
            Main main = new Main();
            incrementX(main);
        }
    
        private static void incrementX(Main main) {
            main.x++;
        }
    }
    

    inc

    public class Main {
    
        private static final IntFunction<Integer> INC = val -> val + 1;
    
        private int x = 42;
    
        public static void main(String[] args) {
            Main main = new Main();
            main.x = INC.apply(main.x);
        }
    
    }