如何在 Java 中使用输出参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2824910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use an output parameter in Java?
提问by soclose
Could someone please give me some sample code that uses an output parameter in function? I've tried to Google it but just found it just in functions. I'd like to use this output value in another function.
有人可以给我一些在函数中使用输出参数的示例代码吗?我试过谷歌它,但只是在函数中找到它。我想在另一个函数中使用这个输出值。
The code I am developing intended to be run in Android.
我正在开发的代码旨在在 Android 中运行。
采纳答案by polygenelubricants
Java passes by value; there's no out
parameter like in C#.
Java按值传递;没有out
像 C# 那样的参数。
You can either use return
, or mutate an object passed asa reference (byvalue).
您可以使用return
或改变作为引用(按值)传递的对象。
Related questions
相关问题
Code sample
代码示例
public class FunctionSample {
static String fReturn() {
return "Hello!";
}
static void fArgNoWorkie(String s) {
s = "What am I doing???"; // Doesn't "work"! Java passes by value!
}
static void fMutate(StringBuilder sb) {
sb.append("Here you go!");
}
public static void main(String[] args) {
String s = null;
s = fReturn();
System.out.println(s); // prints "Hello!"
fArgNoWorkie(s);
System.out.println(s); // prints "Hello!"
StringBuilder sb = new StringBuilder();
fMutate(sb);
s = sb.toString();
System.out.println(s); // prints "Here you go!"
}
}
See also
也可以看看
As for the codethat OP needs help with, here's a typical solution of using a special value (usually null
for reference types) to indicate success/failure:
至于OP需要帮助的代码,这是使用特殊值(通常null
用于引用类型)来指示成功/失败的典型解决方案:
Instead of:
代替:
String oPerson= null;
if (CheckAddress("5556", oPerson)) {
print(oPerson); // DOESN'T "WORK"! Java passes by value; String is immutable!
}
private boolean CheckAddress(String iAddress, String oPerson) {
// on search succeeded:
oPerson = something; // DOESN'T "WORK"!
return true;
:
// on search failed:
return false;
}
Use a String
return type instead, with null
to indicate failure.
改用String
返回类型, withnull
表示失败。
String person = checkAddress("5556");
if (person != null) {
print(person);
}
private String checkAddress(String address) {
// on search succeeded:
return something;
:
// on search failed:
return null;
}
This is how java.io.BufferedReader.readLine()
works, for example: it returns instanceof String
(perhaps an empty string!), until it returns null
to indicate end of "search".
这就是java.io.BufferedReader.readLine()
工作原理,例如:它返回instanceof String
(可能是一个空字符串!),直到它返回null
以指示“搜索”结束。
This is not limited to a reference type return value, of course. The key is that there has to be some special value(s) that is never a valid value, and you use that value for special purposes.
当然,这不仅限于引用类型的返回值。关键是必须有一些永远不是有效值的特殊值,并且您将该值用于特殊目的。
Another classic example is String.indexOf
: it returns -1
to indicate search failure.
另一个经典的例子是String.indexOf
:它返回-1
表示搜索失败。
Note: because Java doesn't have a concept of "input" and "output" parameters, using the
i-
ando-
prefix (e.g.iAddress
,oPerson
) is unnecessary and unidiomatic.
注意:因为 Java 没有“输入”和“输出”参数的概念,所以使用
i-
和o-
前缀(例如iAddress
,oPerson
)是不必要的和单调的。
A more general solution
更通用的解决方案
If you need to return several values, usually they're related in some way (e.g. x
and y
coordinates of a single Point
). The best solution would be to encapsulate these values together. People have used an Object[]
or a List<Object>
, or a generic Pair<T1,T2>
, but really, your own type would be best.
如果您需要返回多个值,通常它们以某种方式相关(例如x
和y
单个 的坐标Point
)。最好的解决方案是将这些值封装在一起。人们使用了 anObject[]
或 a List<Object>
,或泛型Pair<T1,T2>
,但实际上,您自己的类型最好。
For this problem, I recommend an immutable SearchResult
type like this to encapsulate the boolean
and String
search results:
对于这个问题,我建议一个不变的SearchResult
类型这样的封装boolean
和String
搜索结果:
public class SearchResult {
public final String name;
public final boolean isFound;
public SearchResult(String name, boolean isFound) {
this.name = name;
this.isFound = isFound;
}
}
Then in your search function, you do the following:
然后在您的搜索功能中,您执行以下操作:
private SearchResult checkAddress(String address) {
// on address search succeed
return new SearchResult(foundName, true);
:
// on address search failed
return new SearchResult(null, false);
}
And then you use it like this:
然后你像这样使用它:
SearchResult sr = checkAddress("5556");
if (sr.isFound) {
String name = sr.name;
//...
}
If you want, you can (and probably should) make the final
immutable fields non-public
, and use public
getters instead.
如果您愿意,您可以(并且可能应该)将final
不可变字段设为 non- public
,并改用public
getter。
回答by SingleShot
Java does not support output parameters. You can use a return value, or pass in an object as a parameter and modify the object.
Java 不支持输出参数。您可以使用返回值,也可以将对象作为参数传入并修改该对象。
回答by medopal
You can either use:
您可以使用:
return X. this will return only one value.
return object. will return a full object. For example your object might include X, Y, and Z values.
pass array. arrays are passed by reference. i.e. if you pass array of integers, modified the array inside the method, then the original code will see the changes.
返回 X。这将只返回一个值。
返回对象。将返回一个完整的对象。例如,您的对象可能包括 X、Y 和 Z 值。
通过数组。数组是通过引用传递的。即如果您传递整数数组,在方法内部修改数组,那么原始代码将看到更改。
Example on passing Array.
传递数组的示例。
void methodOne{
int [] arr = {1,2,3};
methodTwo(arr);
...//print arr here
}
void methodTwo(int [] arr){
for (int i=0; i<arr.length;i++){
arr[i]+=3;
}
}
This will print out: 4,5,6.
这将打印出:4,5,6。
回答by soclose
Thank you. I use passing in an object as a parameter. My Android code is below
谢谢你。我使用传入一个对象作为参数。我的Android代码如下
String oPerson= null;
if (CheckAddress("5556", oPerson))
{
Toast.makeText(this,
"It's Match! " + oPerson,
Toast.LENGTH_LONG).show();
}
private boolean CheckAddress(String iAddress, String oPerson)
{
Cursor cAddress = mDbHelper.getAllContacts();
String address = "";
if (cAddress.getCount() > 0) {
cAddress.moveToFirst();
while (cAddress.isAfterLast() == false) {
address = cAddress.getString(2).toString();
oPerson = cAddress.getString(1).toString();
if(iAddress.indexOf(address) != -1)
{
Toast.makeText(this,
"Person : " + oPerson,
Toast.LENGTH_LONG).show();
System.out.println(oPerson);
cAddress.close();
return true;
}
else cAddress.moveToNext();
}
}
cAddress.close();
return false;
}
The result is
结果是
Person : John
It's Match! null
人:约翰
这是比赛!空值
Actually, "It's Match! John"
实际上,“这是比赛!约翰”
Please check my mistake.
请检查我的错误。
回答by edvox1138
This is not accurate ---> "...* pass array. arrays are passed by reference. i.e. if you pass array of integers, modified the array inside the method.
这不准确 ---> "...* 传递数组。数组是通过引用传递的。即,如果您传递整数数组,请修改方法内的数组。
Every parameter type is passed by value in Java. Arrays are object, its object reference is passed by value.
在 Java 中,每个参数类型都是按值传递的。数组是对象,它的对象引用是按值传递的。
This includes an array of primitives (int, double,..) and objects. The integer valueis changed by the methodTwo() but it is still the same arr object reference, the methodTwo() cannot add an array element or delete an array element. methodTwo() cannot also, create a new array then set this new array to arr. If you really can pass an array by reference, you can replace that arr with a brand new array of integers.
这包括一组原语(int、double、..)和对象。整数值被methodTwo()改变了但仍然是相同的arr对象引用,methodTwo()不能添加数组元素或删除数组元素。methodTwo() 也不能,创建一个新数组然后将此新数组设置为 arr。如果你真的可以通过引用传递一个数组,你可以用一个全新的整数数组替换那个 arr。
Every object passed as parameter in Java is passed by value, no exceptions.
在 Java 中作为参数传递的每个对象都是按值传递的,没有例外。
回答by Wolfgang Fahl
As a workaround a generic "ObjectHolder" can be used. See code example below.
作为解决方法,可以使用通用的“ObjectHolder”。请参阅下面的代码示例。
The sample output is:
示例输出为:
name: John Doe
dob:1953-12-17
name: Jim Miller
dob:1947-04-18
so the Person parameter has been modified since it's wrapped in the Holder which is passed by value - the generic param inside is a reference where the contents can be modified - so actually a different person is returned and the original stays as is.
所以 Person 参数已经被修改,因为它被包裹在按值传递的 Holder 中 - 里面的通用参数是一个可以修改内容的引用 - 所以实际上返回了一个不同的人,原始保持原样。
/**
* show work around for missing call by reference in java
*/
public class OutparamTest {
/**
* a test class to be used as parameter
*/
public static class Person {
public String name;
public String dob;
public void show() {
System.out.println("name: "+name+"\ndob:"+dob);
}
}
/**
* ObjectHolder (Generic ParameterWrapper)
*/
public static class ObjectHolder<T> {
public ObjectHolder(T param) {
this.param=param;
}
public T param;
}
/**
* ObjectHolder is substitute for missing "out" parameter
*/
public static void setPersonData(ObjectHolder<Person> personHolder,String name,String dob) {
// Holder needs to be dereferenced to get access to content
personHolder.param=new Person();
personHolder.param.name=name;
personHolder.param.dob=dob;
}
/**
* show how it works
*/
public static void main(String args[]) {
Person jim=new Person();
jim.name="Jim Miller";
jim.dob="1947-04-18";
ObjectHolder<Person> testPersonHolder=new ObjectHolder(jim);
// modify the testPersonHolder person content by actually creating and returning
// a new Person in the "out parameter"
setPersonData(testPersonHolder,"John Doe","1953-12-17");
testPersonHolder.param.show();
jim.show();
}
}
回答by Muhammad Soliman
Wrap the value passed in different classes that might be helpful doing the trick, check below for more real example:
包装在不同类中传递的值,这可能有助于实现技巧,请查看下面的更真实示例:
class Ref<T>{
T s;
public void set(T value){
s = value;
}
public T get(){
return s;
}
public Ref(T value) {
s = value;
}
}
class Out<T>{
T s;
public void set(T value){
s = value;
}
public T get(){
return s;
}
public Out() {
}
}
public static void doAndChangeRefs (Ref<String> str, Ref<Integer> i, Out<String> str2){
//refs passed .. set value
str.set("def");
i.set(10);
//out param passed as null .. instantiate and set
str2 = new Out<String>();
str2.set("hello world");
}
public static void main(String args[]) {
Ref<Integer> iRef = new Ref<Integer>(11);
Out<String> strOut = null;
doAndChangeRefs(new Ref<String>("test"), iRef, strOut);
System.out.println(iRef.get());
System.out.println(strOut.get());
}