我知道Java中的所有东西都是通过值传递的,但是下面的代码不应该打印2而不是1。
我所做的就是通过Integer并改变它的值。为什么打印1而不是2?
public static Integer x;
public static void doChange(Integer x) {
x = 2;
}
public static void main(String arg[]) {
x = 1;
doChange(x);
System.out.println(x);
}
在doChange中,x是参数变量,而不是全局静态x。
但参数变量指向全局静态变量。
你从哪里学来的?指向全局变量的参数?
为什么要将参数x传递给doChange()。您可以简单地修改x而不将其作为参数传递,您的目的到底是什么?
我在一次采访中被问到这个问题。
非常感谢你的回答。我想我现在知道引擎盖下面发生了什么。我认为我看不到主函数的变化的原因是整数是不可变的,当我给它赋值时,它会创建新的对象并赋值给引用x;
如果我们能用可变数据重复同样的例子,我们会看到不同的输出。
public static StringBuilder x;
public static void doChange(StringBuilder x)
{
x.append("world");
}
public static void main(String arg[]) {
x = new StringBuilder("hello");
doChange(x);
System.out.println(x);
}
输出:Hello World
装箱的int仍然不变,doChange中的x是指参数,而不是字段。为了显示正在发生的事情,这里是显式装箱的代码版本。
public static Integer x;
// parameter 'x' is hiding field 'x'
public static void doChange(Integer x)
{
// Update parameter 'x', not field 'x', to point to
// new Integer object with value 2.
// Since 'x' is by-value, caller will not see change
x = Integer.valueOf(2);
}
public static void main(String arg[]) {
x = Integer.valueOf(1);
doChange(x);
System.out.println(x);
}
您更改了参数,而不是类变量。重命名参数,它将起作用:
public static void doChange(Integer unused)
{
x = 2;
}
原因是通过赋值(=)更改了实例。您的参数x被分配给了一个新实例(而不是您通过方法调用给它的实例)。解决方案是调用实例方法来更改实例的状态。但是:标量的对象类与其他类不同。整数实例是唯一的(不可变),不能更改整数实例的状态。
但是,如果您尝试使用自己的类(如mynumber)并使用实例方法调用(而不是assignment=),它将按预期工作:
public class MyNumber {
private int number = 0;
public set(int v) {
number = v;
}
public get() {
return number;
}
public String toString() {
return Integer.toString(number);
}
}
如果使用mynumber而不是integer,请将方法dochange更改为:
public static void doChange(MyNumber x)
{
x.set(2);
}
当然,把声明改为:
public static MyNumber x;
…第一个任务主要是:
x.set(1);
希望这有助于理解。
这就是您在代码中解决问题的方法。我编了一个班级,叫La。注意doChange()方法中的La.x = 2;语句。
public class La {
public static Integer x;
public static void doChange(Integer x) {
La.x = 2;
}
public static void main(String arg[]) {
x = 1;
doChange(x);
System.out.println(x);
}
}
您正在将一个整数对象传递给dochange函数。在doOxEnter()中,您正在分配一个新的值,Java是自动装箱,即创建一个值为2的新整数对象并使参数指向它。
指向对象的变量基本上是指向内存地址的指针:请参阅以下答案:https://stackoverflow.com/a/1750197/2698109和https://stackoverflow.com/a/1750141/2698109
public static Integer x; // an primitive Object
// passing an object
public static void doChange(Integer x) {
// under the hood Java is doing this
x = new Integer(2);
}
将方法签名更改为
public static void doChange(int x) {
它应该像预期的那样工作。
你自己回答了问题:)。
由于通过值传递,dochange()方法将具有值的副本。所以无论它在该方法中做什么,它都不会影响在主方法中声明的实际"x"变量。