有人可以给我一些在函数中使用输出参数的示例代码吗?我试过谷歌它,但只是在功能中找到它。我想在另一个函数中使用此输出值。
我正在开发的代码旨在在Android中运行。
答案 0 :(得分:104)
Java按值传递;在C#中没有out
参数。
您可以使用return
,也可以将传递的对象变为引用(按值)。
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!"
}
}
至于OP需要帮助的code,这是使用特殊值(通常null
作为参考类型)来表示成功/失败的典型解决方案:
而不是:
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;
}
使用String
返回类型,而null
表示失败。
String person = checkAddress("5556");
if (person != null) {
print(person);
}
private String checkAddress(String address) {
// on search succeeded:
return something;
:
// on search failed:
return null;
}
这就是java.io.BufferedReader.readLine()
的工作原理,例如:它返回instanceof String
(可能是一个空字符串!),直到它返回null
来表示“搜索”结束。
当然,这不仅限于参考类型返回值。关键是必须有一些永远不是有效值的特殊值,并且您将该值用于特殊目的。
另一个经典示例是String.indexOf
:它返回-1
以表示搜索失败。
注意:因为Java没有“输入”和“输出”参数的概念,使用
i-
和o-
前缀(例如{{1} },iAddress
)是不必要且单一的。
如果您需要返回多个值,通常它们会以某种方式相关(例如,单个oPerson
的{{1}}和x
坐标。最好的解决方案是将这些值封装在一起。人们使用y
或Point
或通用Object[]
,但实际上,您自己的类型最好。
针对此问题,我建议使用这样的不可变List<Object>
类型来封装Pair<T1,T2>
和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;
}
}
如果您愿意,您可以(也可能应该)将private SearchResult checkAddress(String address) {
// on address search succeed
return new SearchResult(foundName, true);
:
// on address search failed
return new SearchResult(null, false);
}
不可变字段设为非SearchResult sr = checkAddress("5556");
if (sr.isFound) {
String name = sr.name;
//...
}
,并改为使用final
getter。
答案 1 :(得分:6)
Java不支持输出参数。您可以使用返回值,或将对象作为参数传入并修改对象。
答案 2 :(得分:5)
作为一种解决方法,可以使用通用的“ObjectHolder”。请参阅下面的代码示例
示例输出为:
name: John Doe
dob:1953-12-17
name: Jim Miller
dob:1947-04-18
所以Person参数已被修改,因为它被包装在Holder中,它通过值传递 - 内部的泛型param是一个可以修改内容的引用 - 所以实际上返回了一个不同的人并且原始保持原样。
/**
* 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();
}
}
答案 3 :(得分:4)
您可以使用:
返回X.这将只返回一个值。
返回对象。将返回一个完整的对象。例如,您的对象可能包含X,Y和Z值。
传递数组。数组通过引用传递。即如果传递整数数组,修改方法内的数组,则原始代码将看到更改。
传递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;
}
}
这将打印出来:4,5,6。
答案 4 :(得分:3)
包装在不同类中传递的值可能有助于实现这一技巧,请查看下面的更多实例:
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());
}
答案 5 :(得分:1)
这不准确---&gt; “... *传递数组。数组通过引用传递。即如果传递整数数组,则修改方法内的数组。
每个参数类型都在Java中通过值传递。数组是对象,其对象引用按值传递。
这包括一个基元数组(int,double,..)和对象。整数值由methodTwo()更改,但它仍然是相同的arr对象引用,methodTwo()无法添加数组元素或删除数组元素。 methodTwo()也不能,创建一个新数组,然后将这个新数组设置为arr。如果你真的可以通过引用传递一个数组,你可以用一个全新的整数数组替换那个arr。
在Java中作为参数传递的每个对象都是按值传递的,没有例外。
答案 6 :(得分:0)
谢谢。我使用传入一个对象作为参数。我的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;
}
结果是
人:约翰
这是匹配!空
实际上,“这是匹配!约翰”
请检查我的错误。