2011-12-02 19 views
2

问这样一个原始问题的道歉。如何在java中实现int in/out参数

我写了一个函数带了一个参数;这个参数应该是一个输入/输出参数。

调试后,我意识到,由于在java中没有明确的引用类型,我应该使用Integer对象(而不是int primitive)作为参数类型。所以我改变了我的功能:

boolean getNextFoo(int currentFoo) { 
    currentFoo = currentFoo + 1; 
} 

到:

boolean getNextFoo(Integer currentFoo) { 
    currentFoo = currentFoo + 1; 
} 

检查调试器中执行后,我意识到这有相同的结果以前。也就是说,我通过的对象getNextFoo()不会更改。

问题1:如何使用Java实现in/out参数(更具体地用于基本类型)。我想(原谅我)对象总是通过引用传递。

问题2:我在互联网上查找答案并阅读Integer是不可变的。我理解不变的手段是不变的。如果是这样,为什么编译器(解释器?)在getNextFoo函数中做currentFoo = currentFoo + 1时抱怨?

PS:我看到在Integer对象实际上没有被传递到getNextFoo调试器,而不是Integer.valueOf值被传递到getNextFoo这是留给我更糊涂了。

回答

1

答1:

一种方法是在一个AtomicInteger传递,这是可变

boolean getNextFoo(AtomicInteger foo) { 
    foo.set(foo.get() + 1); 
    return true; 
} 

答2:

的语句:currentFoo = currentFoo + 1不修改所述对象;它正在创建新Integer实例重新分配本地参考以指向它。

当您退出该方法时,本地参考将“丢失”(即超出范围),因此重新分配该方法的无效以外的方法。

+0

我猜想它正在用'(currentFoo + 1)'的值创建一个新的Integer实例。但是'整数'也是一个对象。如果我不能'myObject = myOldObject'来创建'myOldObject'的副本,编译器如何创建一个也是对象的Integer副本?如果我的意图是创建一个副本,我必须在myOldObject类中定义一个拷贝构造函数,以便能够复制它。即使这样,我也必须显式调用myObject = new MyObject(myOldObject)来获取副本。 –

0

整数是不可变的,这就是为什么它的值不能改变。

当我这样做,为什么不编译器(翻译吗?)抱怨currentFoo = currentFoo + 1

因为当u做currentFoo = currentFoo + 1一个新的整数上堆和其参考创建被分配给currentFoo。

对于Integer,如果您想要在函数外获得更改的值,您可以从函数返回值,您可以将该整数放入array/ArrayList并将该Array ArrayList传递给该函数。现在得到改变的价值,它会反映在功能之外。

0

问题1:如何使用Java实现输入/输出参数(更多 专用于原始类型)。我想(原谅我)反对 总是通过引用传递。

传递具有int类型的成员变量的可变类对象和更新通该对象的成员变量。

问题2:我正在网上查找答案并阅读 Integer是不可变的。我理解不变的手段是不变的。如果是这样, 为什么不编译器(翻译吗?)抱怨,当我做currentFoo = currentFoo + 1 getNextFoo函数内?

新对象将被创建并将被分配到currentFoo

0

问题2:在一个新的对象与结果工作时调用currentFoo = currentFoo + 1被创建,其引用存储在currentFoo。编译器不会抱怨,因为它不是无效的Java - 它只是导致创建一个新对象,而不是当前正在更新的对象。

2

Q1:在Java中参数总是按值传递。在对象的情况下,你通过引用,而不是参考本身的(这是经常混淆的原因)。要实现输入/输出参数,必须传递一个对象,该对象持有对实参数的引用。

Q2:不可变意味着对象不能修改,但变量可以。所以currentFoo = currentFoo + 1意味着:创建具有价值currentFoo + 1一个新的整数,然后分配这个新对象currentFoo。

+0

我猜想它正在用'(currentFoo + 1)'的值创建一个新的Integer实例。但是'整数'也是一个对象。如果我不能'myObject = myOldObject'来创建'myOldObject'的副本,编译器如何创建一个也是对象的Integer副本?如果我的意图是创建一个副本,我必须在myOldObject类中定义一个拷贝构造函数,以便能够复制它。即使这样,我也必须显式调用myObject = new MyObject(myOldObject)来获取副本。 –

+0

'currentFoo = currentFoo + 1'其实基本上等同于'currentFoo = new Integer(currentFoo + 1)' – Viruzzo

0

问题1:

你可以通过1个int数组,并改变独特元素值,或通过一个可变的整数包装对象(如AtomicInteger,例如)。或者,而不是使用in/out参数,您的方法可能会返回包含布尔字段和整数字段的对象。

问题2:

currentFoo = currentFoo + 1 

是相同的:

int tmp = currentFoo.intValue(); // auto-unboxing 
tmp = tmp + 1; 
currentFoo = Integer.valueOf(tmp); // auto-boxing 

一个新的整数实例因而分配给currentFoo。原始实例(不可变)不会被修改。

所有参数由Java的值传递。当使用对象时,对对象的引用被传递,并且按值传递:引用的副本被创建并传递给方法。如果将某些内容分配给传入的引用,则将其分配给副本,并且原始引用仍然指向原始对象。