场景是这样的,有个局部变量a,传给方法A然后在A方法里面赋值,接着又传给方法B,在方法B里面取值。也就是业务需求希望通过A改变a的值来控制B的执行逻辑。这就要涉及到JAVA中参数的值传递和引用传递。先用基本类型boolean来实现一下,代码如下:
public class ComTest {
@Test
public void testT() {
boolean a = false;
funA(a);
funB(a);
}
public void funA(boolean a) {
a = true;
}
public void funB(boolean a) {
if (a) {
System.out.println("change success");
} else {
System.out.println("nothing happen");
}
}
}
结果打印的是nothing happen,a值没有被修改,这是因为基本数据类型(如int、float、double等)是通过值传递的,在执行过程中程序将变量a的值复制一份传递给了方法A和方法B,而不是传递变量本身。
既然基本数据类型不行,换成封装类型Boolean试试。
public class ComTest {
@Test
public void testT() {
Boolean a = false;
funA(a);
funB(a);
}
public void funA(Boolean a) {
a = true;
}
public void funB(Boolean a) {
if (a) {
System.out.println("change success");
} else {
System.out.println("nothing happen");
}
}
}
结果还是nothing happen,这是乍回事?那换成字符串再看看。
public class ComTest {
@Test
public void testT() {
String a = "0";
funA(a);
funB(a);
}
public void funA(String a) {
a = "1";
}
public void funB(String a) {
if ("1".equals(a)) {
System.out.println("change success");
} else {
System.out.println("nothing happen");
}
}
}
打印结果还是没变化,虽然已经不用基本类型,但还是赋值不成功,这是因为在Java中,对于不可变对象(如Boolean、String等),每次对其进行修改时都会创建一个新的对象来代替新的值,原始的对象保持不变,不受修改的影响,从而提供更好的线程安全性。
注意,在Java中,以下对象是不可变的。
1、String类的对象。一旦创建了一个String对象,它的值就不能被改变。
2、BigInteger和BigDecimal类的对象。这两个类提供了不可变的数值对象。
3、基本数据类型(byte, short, int, long, float, double, boolean)的封装类型(例如Byte, Short, Integer, Long, Float, Double, Boolean)都是不可变的。
4、枚举类型(enum)。
5、一些java集合类的部分实现,比如Arrays.asList()返回的列表,Collections.unmodifiableList()返回的列表等。
6、java.lang.Object类中的final字段,如果一个字段被声明为final,那么这个字段的值就不能被修改。
7、java.lang.Math类中的所有静态字段,如PI和E等。
8、java.lang.Runtime类中的freeMemory()和totalMemory()方法返回的值也是不可变的。
既然以上方法的都不满足,只好使用对象的引用传递了,重新定义一个新的对象,对对象内的属性赋值,然后再在方法中传递。
public class ComTest {
@Test
public void testT() {
Flag flag = new Flag();
funA(flag);
funB(flag);
}
public void funA(Flag a) {
a.setA(true);
}
public void funB(Flag a) {
if (a.isA()) {
System.out.println("change success");
} else {
System.out.println("nothing happen");
}
}
@Data
class Flag {
boolean a = false;
}
}
//打印结果
//change success
引用传递与值传递不同,它实际上是将实际参数的内存地址传递给方法。因此,在方法内部对参数进行修改会影响到实际参数的值,所以可以实现方法间变量的传递。
原文始发于微信公众号(程序员小义):写了那么多年代码,还犯这么低级的错误!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/218380.html