Java传递值:为什么列表在移交给另一个类时会发生变化?
我正在为我的学校研究一个Java问题,它给了我这个实用程序类:Java传递值:为什么列表在移交给另一个类时会发生变化?,java,pass-by-reference,pass-by-value,Java,Pass By Reference,Pass By Value,我正在为我的学校研究一个Java问题,它给了我这个实用程序类: import java.util.*; public class PassByValue { private PassByValue() {} public static void add(int a) { a = a + 1; } public static void add(Set<String> b) { b = new Has
import java.util.*;
public class PassByValue
{
private PassByValue() {}
public static void add(int a)
{
a = a + 1;
}
public static void add(Set<String> b)
{
b = new HashSet<String>();
b.add("ABC");
}
public static void add(List<Integer> c)
{
c.add(new Integer(1));
}
}
import java.util.*;
公共类PassByValue
{
私有PassByValue(){}
公共静态无效添加(int a)
{
a=a+1;
}
公共静态无效添加(集合b)
{
b=新的HashSet();
b、 添加(“ABC”);
}
公共静态无效添加(列表c)
{
c、 加(新整数(1));
}
}
它还为我提供了这个类的main方法
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PassByValueClient
{
public static void main(String[] args)
{
PrintStream output = System.out;
int a = 1;
PassByValue.add(a);
output.println(a);
Set<String> b = new HashSet<String>();
PassByValue.add(b);
output.println(b.size());
List<Integer> c = new ArrayList<Integer>();
PassByValue.add(c);
output.println(c.size());
}
}
导入java.io.PrintStream;
导入java.util.ArrayList;
导入java.util.HashSet;
导入java.util.List;
导入java.util.Set;
公共类PassByValueClient
{
公共静态void main(字符串[]args)
{
PrintStream输出=System.out;
INTA=1;
PassByValue.add(a);
输出println(a);
Set b=新的HashSet();
PassByValue.add(b);
output.println(b.size());
列表c=新的ArrayList();
PassByValue.add(c);
println(c.size());
}
}
我们应该预测产量。当我预测输出时,我的猜测分别是
1
、0
、和0
。然而,当我运行代码时,我得到的输出分别是1
、0
、和1
。根据我对将参数/参数传递到方法的理解,客户机的代码应该保持不变。有人能告诉我为什么输出是1
而不是0
这是因为传递给PassByValue.add()的列表指向存储中的某个位置(地址),即列表中的某个位置(比如地址42)。当列表位于.add()方法中时,它仍然指向相同的地址(42)
如果你改变它,地址(42)上的数据也会改变。但两个列表仍然指向相同的地址(42),因此它们指向相同的数据
我想用图片解释一下你的例子中发生了什么:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
变量“a”
这将在存储器中创建一个地址,变量a
指向该地址:
然后将其传递给方法PassByValue.add(a)
时,将创建一个新变量。但是这个新变量指向相同的地址(值)
然后使用a=a+1
对其进行更改时,该变量不再指向地址,而是指向一个新地址,并带有一个新值。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
变量“b”
声明时,将创建指向特定地址的对象:
当您将其移交时,会创建另一个对象,该对象指向同一地址:
在PassByValue.add()中将对象设置为=newhashset()时代码>,它指向另一个地址
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
变量“c”
更改对象本身时,情况会有所不同。
就像你用清单做的一样。
通过创建ListList c=new ArrayList()代码>变量指向特定地址
当您将它交给.add()
-方法时,将创建一个新变量,但它指向相同的地址
当你改变它的时候,说c.add(新的整数(1))代码>更改对象本身。当您更改对象本身时,存储在该地址上的数据会发生更改,但不会创建新的地址空间,而且两个变量仍然指向同一地址。
非常感谢您!这对变量b真的很有帮助,它是否因为实例化了一个新的HashSet对象而指向内存中的另一个地址?没错-我更新了变量b的答案@EdShirinian如果答案解决了您的问题,请接受答案(否则问题会一直悬而未决)。当使用int a=1
时,您的解释不正确,当使用整数a=1
时,您的解释是正确的。像int
这样的原语不会像您在解释中使用的那样作为引用。Java总是按值传递,但是像List
这样的引用类型的值是引用,因此称为“引用类型”
Integer a = 1