参数传递问题

时间:2022-08-29 21:10:01

public class myFz {
        public static  void   fz(Integer   a,Integer   b)
{     
  a=9;
  b=8;
        }

      public static void main(String[] args) {
// TODO Auto-generated method stub
Integer a=new Integer(10),b=new Integer(90);
mySwap.fz(a,b);
System.out.println(a);
System.out.println(b);

}
}


想请问为什么不能实现重新赋值啊
参数是什么传递方式呢?
能不能给我个存储模型示意图?

谢谢

10 个解决方案

#1



1) 局部变量 
      定义在方法内部,其作用域为所在代码块,也称为临时变量、栈变量。 
存在于栈中。
   2) 实例变量 
      定义在类内部方法之外,其作用域为整个类。如未定义初值,系统会自动为其赋黙认值。存在于堆中
默认数值
      类型                     黙认值 
      byte                     0 
      short                    0 
      int                      0 
      long                     0L 
      float                    0.0f 
      double                   0.0d 
      char                     '\u0000' 空格
      boolean                  false 
      *All reference types      null


你输出的是 a对象
而 a=9;是一个引用


package com.csdn;

import java.util.ArrayList;

public class TestFanxin {
 public static  void   fz(Integer   a,Integer   b)
    {     
          a=9;
          b=8;
        }

      public static void main(String[] args) {
        // TODO Auto-generated method stub
        Integer a=new Integer(10),b=new Integer(90);
        fz(a,b);
        
        System.out.println(b);
        //输出对象
        TestFanxin test = new TestFanxin();
        User u  =test.new User("super对象");
        System.out.println(u);
        System.out.println(u.name);

    }
      class User {
       String name = "123引用";
       User(String name){
       this.name = "super";
       }
      }

}

#2


看http://topic.csdn.net/u/20090523/21/c6c9028b-04de-4aef-8b9e-f63e8eb29864.html
这个帖子,5楼的回复,画图了,很方便理解。


#3


引用 2 楼 ZangXT 的回复:
看http://topic.csdn.net/u/20090523/21/c6c9028b-04de-4aef-8b9e-f63e8eb29864.html 
这个帖子,5楼的回复,画图了,很方便理解。 



但是赋值是改变了对象本身的内容吧

是指向的对象变啦而指向的对象的地址没变啊?

#4


引用 3 楼 binzai325 的回复:
引用 2 楼 ZangXT 的回复:

看http://topic.csdn.net/u/20090523/21/c6c9028b-04de-4aef-8b9e-f63e8eb29864.html 
这个帖子,5楼的回复,画图了,很方便理解。 

但是赋值是改变了对象本身的内容吧 

是指向的对象变啦而指向的对象的地址没变啊?


你的是plain class---说白了就是一个普通的栈对象,方法弹栈的时候就消失了。

a赋值。
b赋值

调用函数的时候 b弹栈,a弹栈.---方法调用完毕值消失。 对于一个普通的值对象你认为它还有放进堆中的必要么?

像大家说的那个什么对象就是引用,根本就是谬论,对象也要看是不是放在堆中。这话说完估计就一堆人PK我!!!!

程序在编译的时候方法分配了一段内存,而且分配了入口地址。java 不但有一个独特的值地址,而且名称在局部也可以引用地址。

如果你这么写:
 public class User{
 User(int a){
  this.a=a;
 }
 int a=0;
 }
swap(User a User b)
看看结果!!
为什么啊?
就是此时User进入了堆中,这个时候的a引用在栈中指向了堆。

a--->对象 (对象在栈中,方法调用就结束了,对象在堆中,方法调用完毕一样存在,JVM要是恶意回收那也没办法)


#5


顶!

#6


Integer也是基础类型来的,凡是八个基础类型都是值传递
其它的就是引用传递了

#7


java是只有传值...

#8


应该是这八个基本数据类型所对应的封装类和String一样具有不可变性。
lz可以参考一下:

public class ParamTest {

public void changeInt(int a) {
a = 3;
}

public void changePoint(Point point) {
point.x = 5;
point.y = 6;
}

public void changeString(String str) {
str = "xyz";
}

public void change(char c, char[] ch) {
c = 'B';
ch[0] = 'Z';
}

public static void main(String[] args) {

// 第一个测试
int a = 1;
ParamTest test = new ParamTest();
test.changeInt(a);
System.out.println(a);

// 第二个测试------Java中的方法参数传递机制
// Point point = new Point(1, 2);
// ParamTest test = new ParamTest();
// test.changePoint(point);
// System.out.println(point.x);
// System.out.println(point.y);// 这说明是pass by value(对象传递它的引用)

// 第三个测试------String的不可变性
// String s = "abc";
// ParamTest test = new ParamTest();
// test.changeString(s);
// System.out.println(s);

// 第四个测试
// char c='A';
// char[] ch=new char[]{'M','N','P'};//数组也是对象(引用数据类型)
// ParamTest test=new ParamTest();
// test.change(c, ch);
// System.out.println(c);
// System.out.println(ch[0]);
}
}

class Point {
int x;

int y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}

}

#9


之所以不能实现交换呢,你这个问题昨天已经在你的第一个帖子中有了最详细的解释,也是最彻底的解释(火龙果)。
我以前也不太明白,借楼主的帖子也让我明白了很多,在此也感谢一下楼主。
虽然是初学者,但也想发表一下自己的观点。大致就是一楼的那个观点,方法中参数的引用是有生命周期的。

public class SwapTest 
{
    public static  void   fz(Integer   a,Integer   b)
    {     
      a = new Integer(9);
      b = new Integer(99);     
    }

    public static void main(String[] args)
    {             
      Integer c=new Integer(10),d=new Integer(90);
      
      SwapTest.fz(c,d);
      
      System.out.println(c);
      System.out.println(d);
    }
}

上面这种情况不能实现交换。因为Integer a ,a这个引用的作用域就是fz这个方法中,出去这个方法它的作用就消失了。
b 也是一样的道理。所以SwapTest.fz(c,d);后没有达到想要的效果。
换一种方式,验证一下说的是否正确。将输出语句放在fz这个方法中。

public class SwapTest 
{
    public static  void   fz(Integer   a,Integer   b)
    {     
      a = new Integer(9);
      b = new Integer(99);
      System.out.println(a);
      System.out.println(b);
    }

    public static void main(String[] args)
    {             
      Integer c=new Integer(10),d=new Integer(90);
      
      SwapTest.fz(c,d);
      
      //System.out.println(c);
      //System.out.println(d);
    }
}

实现了交换,这就验证了上面说的是正确的。引用是放在栈中的,创建的对象是放在堆中的
要想理解这些应该了解一些堆栈的知识。

#10



也要谢谢楼上的

 都是初学者
 
 以后还要互相学习

 这个问题算是搞懂了
 
  结贴喽!

#1



1) 局部变量 
      定义在方法内部,其作用域为所在代码块,也称为临时变量、栈变量。 
存在于栈中。
   2) 实例变量 
      定义在类内部方法之外,其作用域为整个类。如未定义初值,系统会自动为其赋黙认值。存在于堆中
默认数值
      类型                     黙认值 
      byte                     0 
      short                    0 
      int                      0 
      long                     0L 
      float                    0.0f 
      double                   0.0d 
      char                     '\u0000' 空格
      boolean                  false 
      *All reference types      null


你输出的是 a对象
而 a=9;是一个引用


package com.csdn;

import java.util.ArrayList;

public class TestFanxin {
 public static  void   fz(Integer   a,Integer   b)
    {     
          a=9;
          b=8;
        }

      public static void main(String[] args) {
        // TODO Auto-generated method stub
        Integer a=new Integer(10),b=new Integer(90);
        fz(a,b);
        
        System.out.println(b);
        //输出对象
        TestFanxin test = new TestFanxin();
        User u  =test.new User("super对象");
        System.out.println(u);
        System.out.println(u.name);

    }
      class User {
       String name = "123引用";
       User(String name){
       this.name = "super";
       }
      }

}

#2


看http://topic.csdn.net/u/20090523/21/c6c9028b-04de-4aef-8b9e-f63e8eb29864.html
这个帖子,5楼的回复,画图了,很方便理解。


#3


引用 2 楼 ZangXT 的回复:
看http://topic.csdn.net/u/20090523/21/c6c9028b-04de-4aef-8b9e-f63e8eb29864.html 
这个帖子,5楼的回复,画图了,很方便理解。 



但是赋值是改变了对象本身的内容吧

是指向的对象变啦而指向的对象的地址没变啊?

#4


引用 3 楼 binzai325 的回复:
引用 2 楼 ZangXT 的回复:

看http://topic.csdn.net/u/20090523/21/c6c9028b-04de-4aef-8b9e-f63e8eb29864.html 
这个帖子,5楼的回复,画图了,很方便理解。 

但是赋值是改变了对象本身的内容吧 

是指向的对象变啦而指向的对象的地址没变啊?


你的是plain class---说白了就是一个普通的栈对象,方法弹栈的时候就消失了。

a赋值。
b赋值

调用函数的时候 b弹栈,a弹栈.---方法调用完毕值消失。 对于一个普通的值对象你认为它还有放进堆中的必要么?

像大家说的那个什么对象就是引用,根本就是谬论,对象也要看是不是放在堆中。这话说完估计就一堆人PK我!!!!

程序在编译的时候方法分配了一段内存,而且分配了入口地址。java 不但有一个独特的值地址,而且名称在局部也可以引用地址。

如果你这么写:
 public class User{
 User(int a){
  this.a=a;
 }
 int a=0;
 }
swap(User a User b)
看看结果!!
为什么啊?
就是此时User进入了堆中,这个时候的a引用在栈中指向了堆。

a--->对象 (对象在栈中,方法调用就结束了,对象在堆中,方法调用完毕一样存在,JVM要是恶意回收那也没办法)


#5


顶!

#6


Integer也是基础类型来的,凡是八个基础类型都是值传递
其它的就是引用传递了

#7


java是只有传值...

#8


应该是这八个基本数据类型所对应的封装类和String一样具有不可变性。
lz可以参考一下:

public class ParamTest {

public void changeInt(int a) {
a = 3;
}

public void changePoint(Point point) {
point.x = 5;
point.y = 6;
}

public void changeString(String str) {
str = "xyz";
}

public void change(char c, char[] ch) {
c = 'B';
ch[0] = 'Z';
}

public static void main(String[] args) {

// 第一个测试
int a = 1;
ParamTest test = new ParamTest();
test.changeInt(a);
System.out.println(a);

// 第二个测试------Java中的方法参数传递机制
// Point point = new Point(1, 2);
// ParamTest test = new ParamTest();
// test.changePoint(point);
// System.out.println(point.x);
// System.out.println(point.y);// 这说明是pass by value(对象传递它的引用)

// 第三个测试------String的不可变性
// String s = "abc";
// ParamTest test = new ParamTest();
// test.changeString(s);
// System.out.println(s);

// 第四个测试
// char c='A';
// char[] ch=new char[]{'M','N','P'};//数组也是对象(引用数据类型)
// ParamTest test=new ParamTest();
// test.change(c, ch);
// System.out.println(c);
// System.out.println(ch[0]);
}
}

class Point {
int x;

int y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}

}

#9


之所以不能实现交换呢,你这个问题昨天已经在你的第一个帖子中有了最详细的解释,也是最彻底的解释(火龙果)。
我以前也不太明白,借楼主的帖子也让我明白了很多,在此也感谢一下楼主。
虽然是初学者,但也想发表一下自己的观点。大致就是一楼的那个观点,方法中参数的引用是有生命周期的。

public class SwapTest 
{
    public static  void   fz(Integer   a,Integer   b)
    {     
      a = new Integer(9);
      b = new Integer(99);     
    }

    public static void main(String[] args)
    {             
      Integer c=new Integer(10),d=new Integer(90);
      
      SwapTest.fz(c,d);
      
      System.out.println(c);
      System.out.println(d);
    }
}

上面这种情况不能实现交换。因为Integer a ,a这个引用的作用域就是fz这个方法中,出去这个方法它的作用就消失了。
b 也是一样的道理。所以SwapTest.fz(c,d);后没有达到想要的效果。
换一种方式,验证一下说的是否正确。将输出语句放在fz这个方法中。

public class SwapTest 
{
    public static  void   fz(Integer   a,Integer   b)
    {     
      a = new Integer(9);
      b = new Integer(99);
      System.out.println(a);
      System.out.println(b);
    }

    public static void main(String[] args)
    {             
      Integer c=new Integer(10),d=new Integer(90);
      
      SwapTest.fz(c,d);
      
      //System.out.println(c);
      //System.out.println(d);
    }
}

实现了交换,这就验证了上面说的是正确的。引用是放在栈中的,创建的对象是放在堆中的
要想理解这些应该了解一些堆栈的知识。

#10



也要谢谢楼上的

 都是初学者
 
 以后还要互相学习

 这个问题算是搞懂了
 
  结贴喽!