![](/img/trans.png)
[英]How to invoke method in another class and return value from it in java?
[英]How to Increment a class Integer references value in java from another method
package myintergertest;
/**
*
* @author Engineering
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//this one does not increment
Integer n = new Integer(0);
System.out.println("n=" + n);
Increment(n);
System.out.println("n=" + n);
Increment(n);
System.out.println("n=" + n);
Increment(n);
System.out.println("n=" + n);
Increment(n);
//this one will increment
MyIntegerObj myInt = new MyIntegerObj(1);
Increment(myInt);
System.out.println("myint = " + myInt.get());
Increment(myInt);
System.out.println("myint = " + myInt.get());
Increment(myInt);
System.out.println("myint = " + myInt.get());
}
public static void Increment(Integer n) {
//NO. this doesn't work because a new reference is being assigned
//and references are passed by value in java
n++;
}
public static void Increment(MyIntegerObj n) {
//this works because we're still operating on the same object
//no new reference was assigned to n here.
n.plusplus(); //I didn't know how to implement a ++ operator...
}
}
所有这些的结果是 n=0。 整数 n 是一个对象,因此通过引用传递,那么为什么增量没有反映在调用方方法(main)中? 我预计输出为 n=0 n=1 n=2 等等...
更新:注意我更新了上面的代码示例。 如果我理解正确,Jon Skeet 回答了为什么 myInt 会增加而 n 不会增加的问题。 这是因为 n 正在获取在 Increment 方法中分配的新引用。 但是 myInt 没有被分配一个新的引用,因为它正在调用一个成员函数。
这听起来像我理解正确吗哈哈?
不,对象不是通过引用传递的。 引用是按值传递的 - 有很大的不同。 Integer
是不可变类型,因此您不能在方法中更改值。
你的n++;
声明是有效的
n = Integer.valueOf(n.intValue() + 1);
因此,它为Increment
的变量n
分配了一个不同的值 - 但由于 Java只有按值传递,这不会影响调用方法中n
的值。
编辑:回答您的更新:没错。 大概您的“MyIntegerObj”类型是可变的,并且在您调用plusplus()
时会更改其内部状态。 哦,不要费心四处寻找如何实现运算符 - Java 不支持用户定义的运算符。
您可以使用java.util.concurrent.atomic
的AtomicInteger
。 它有一个适合您展示的 'incrementAndGet' 方法。
您正在寻找类似于 C++ 的参考或 C# 的输出参数的内容。 Java(和许多其他语言)不支持这一点。
这种类型的行为通常是通过将方法从 void 更改为(在这种情况下)int 来实现的: public static int increment(int n) { return ++n; }
public static int increment(int n) { return ++n; }
如果该方法已经返回某些内容,那么您可以创建一个具有两个字段(甚至可以是公共字段)的新类:原始返回值和 n 的新值。
或者,您也可以将整数包装在通用 Cell 类中。 你只需要编写一次这个 Cell 类:
public class Cell<T> {
public Cell(T t) { value = t; }
public void set(T t) { value = t; }
public T get() { return value; }
}
然后,您可以在想要更改原语的方法的所有情况下使用它:
public static void increment(Cell<Integer> n) {
n.set(n.get()++);
}
Cell<Integer> n = new Cell<Integer>(0);
increment(n);
increment(n);
increment(n);
System.out.println(n.get()); // Output: 3
正如 Jon Skeet 所提到的,Java 中的所有方法都是按值传递,而不是按引用传递。 由于引用类型是按值传递的,因此函数体内的内容是引用的副本 - 此副本和原始引用都指向相同的值。
但是,如果您在函数体内重新分配副本,它将对程序的其余部分没有影响,因为该副本将在函数退出时超出范围。
但是考虑到您实际上并不需要通过引用来做您想做的事情。 例如,您不需要增加Integer
的方法 - 您只需在代码中需要增加的点处增加它即可。
对于更复杂的类型,例如在对象上设置某些属性,您正在使用的对象可能是可变的; 在这种情况下,引用的副本就可以正常工作,因为自动取消引用将使您找到您正在调用其 setter 的原始对象。
旁注:以我的拙见,在 Integer 对象上编写 n++ 非常具有误导性。 这依赖于 Java 的一项称为“自动装箱”的功能,它将原语转换为相应的装箱对象——比如 int 到 Integer 或 boolean 到 Boolean——自动且没有警告。 坦率地说,我认为这是一个糟糕的功能。 是的,有时它会自动为您进行方便的转换,从而使您的生活变得更简单,但它也可以执行您不打算或没有意识到正在发生的转换,并产生意想不到的副作用。
无论如何,有两种方法可以完成您显然想要做的事情:
一:让增量函数返回一个带有更新值的新整数。 喜欢:
public Integer increment(Integer n)
{
Integer nPlus=Integer.valueOf(n.intValue()+1);
return nPlus;
}
然后调用它:
Integer n=Integer.valueOf(0);
n=increment(n); // now n==1
n=increment(n); // now n==2
等等。
二:创建自己的类,类似于 Integer 但它是可变的。 喜欢:
class MutableInteger
{
int value;
public MutableInteger(int n)
{
value=n;
}
public void increment()
{
++value;
}
... whatever other functions you need ...
}
当然,最大的收获是您几乎必须重新发明 Integer 类。
你不能。 Java 是严格按值传递的。
见http://javadude.com/articles/passbyvalue.htm
您的选择是将整数包装在一个对象(或数组)中,传入并更新,返回一个值,或者使整数成为类/实例变量。
哪个更好取决于具体情况。
正如DerMike提到的,您可以按如下方式实现:
public void doStuff() {
AtomicInteger i = new AtomicInteger(0);
increment(i);
System.out.println(i);
}
public void increment(AtomicInteger i) {
i.set(i.get() + 1);
}
Integer
是一个值对象,这意味着它的值不能改变。
请注意, n++
等效于n = n + 1
。 您只是在更改局部变量n
引用的值,而不是n
本身的值。
请参阅 AtomicInteger: http : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html
您可以使用这个 java.util.concurrent 类来实现线程安全。
public class passByReferenceExample {
static void incrementIt(Long b[]){
Long c = b[0];
c=c+1;
b[0]=c;
}
public static void main(String[] args) {
Long a[]={1L};
System.out.println("Before calling IncrementIt() : " + a[0]);
System.out.println();
incrementIt(a);
System.out.println("after first call to incrementIt() : " + a[0]);
incrementIt(a);
System.out.println("after second call to incrementIt(): "+ a[0]);
incrementIt(a);
System.out.println("after third call to incrementIt() : "+ a[0]);
incrementIt(a);
System.out.println("after fourth call to incrementIt(): "+ a[0]);
}
}
输出:
Before calling IncrementIt() : 1
after first call to incrementIt() : 2
after second call to incrementIt(): 3
after third call to incrementIt() : 4
after fourth call to incrementIt(): 5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.