繁体   English   中英

Java参数传递问题

[英]Java parameter passing question

我对Java比较陌生,在尝试使用某些代码时遇到了令我惊讶的事情。 希望有人能够对此有所了解。 这是与我的问题相关的一些代码片段。 那些阅读过编程实践的人可能会觉得这很熟悉。

此函数是为List数据类型定义的,并将传递的“fn”参数(只是包装在对象中的函数)应用于列表的所有成员。

    public void apply(MapFunctionI fn, Object fnArg) {
    Node curr = head;
    for (; curr != null; curr = curr.getNext()){
        fn.function(curr.getItem(), fnArg);
    }
}

接下来,我尝试使用这个函数来计算列表中元素的数量,使用实现MapFunctionI的类(一个需要一个名为'function'的方法的接口)

class CounterFunction implements MapFunctionI {
public void function(Object node, Object arg){
    ((MyInteger)arg).increment();
}
}

这是我怎么称呼这个。

    static void TestApply(LinkedList l){
    System.out.println("Number of elements in List -> ");
    MyInteger n = new MyInteger(0);
    l.apply(new CounterFunction(),n);
    System.out.println(n.value());
}

这是MyInteger类型。

class MyInteger {
private int n;

MyInteger(int i){
    n = i;
}

public void increment(){
    n++;
}

public int value(){
    return n;
}

现在,如果您想知道我为什么使用自己的Integer类型,那就是我的问题。 我尝试使用Java Integer类型,但我无法使其工作,打印的答案始终为O,“整数”的值不会在多个调用中持续存在。 我是这样做的,

arg = ((Integer)arg).intValue() + 1;

什么解释了这种行为?

我相信有一个更简洁的方式来提出这个问题:-)

第一个问题是类型Integer是不可变的; 一旦使用某个整数值创建,该值就无法更改。 所以你不能直接改变一个整数(我不是说你不知道这个或试过)。

下一个问题是传递给函数的是对该Integer的引用。 您可以在函数内部将该引用更改为指向不同值的Integer,但是函数内部更改的引用永远不会传递回调用函数,因此其值与此无关。

您的自制类的工作原因是您现在正在更改对象的内部内容而不仅仅是对它的引用。 函数内部和外部都存在相同的对象,因此当您在内部更改它时,确实可以在外部看到更改。

使用Integer类型时它不起作用的原因是因为您正在更新function()中的arg指针的本地副本。 在Java中,所有非基元都是“引用类型”,所有函数参数都是按值传递的。

编辑 - 如果最后一个语句令人困惑,想象一下你是否正在使用C ++方言,它只允许你按值传递引用(即你只能传递指针的副本),并且你想要实现swap函数。 不可能,对吧? 更新本地指针不会影响传递给函数的指针。

首先,Java的Integer类是不可变的; 它只代表一个整数值。 当你在它上面调用intValue() ,它只是返回整数的当前(不可变)值。

当你将(未装箱和重新装箱的)增量值分配给argarg只是对传入内容的本地引用(就像C中函数内的指针值一样)。 设置为某个东西然后从该函数返回会丢失您刚给它的新值。

如果您使用的是C / C ++,那么您可以使用指向指针的指针。 但是Java没有相应的构造,所以你自己处理它 - 你使用的包装器对象是你问题的合理解决方案。

发生这种情况是因为在Java中,参数传递是BY VALUE。 请注意,当您将对象传递给函数时,您将传递BY VALUE其引用...或者,以另一种方式说,您按值传递其地址。

当你写:

arg = .... // a new Integer Object

你在函数中本地更改arg引用的值(指向新对象),而保存在List.apply函数中的fnArg变量中的引用仍然是相同的(因此指向相同的整数(0) )。

如果您了解C ++,那么您在具有int *或int *&作为参数的函数中具有相同的区别:在Java中,它就像拥有int *(对于对象)。

最后一个代码部分的问题是arg变量只保存对Integer类的引用。 当您将arg设置为某个值时,其值将在本地上下文中替换为新对象,并且不会更新已存在的对象。 您必须指定要更新的引用的完整路径。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM