【黑马程序员】Java中方法的参数传递问题

【黑马程序员】Java中方法的参数传递问题
【黑马程序员】Java中方法的参数传递问题

【黑马程序员】Java中方法的参数传递问题最近有很多同学,就算是就业班毕业之后,还依然在问java方法的调用中值的传递问题,实际参数究竟什么时候才会改变?接下来我们先由一个例子来引出大家的问题,请看如下例子,并回答下面代码中的四个问题

public class Demo {

public static void main(String[] args) {

int a = 10;

change(a);

System.out.println(a); // 1:请问输出什么?

String str = "abc";

change(str);

System.out.println(str);// 2:请问输出什么?

Student s = new Student("张三",13);

System.out.println(s); // 输出 Student [name=张三, age=13]

change(s);

System.out.println(s); // 3:请问输出什么?

change1(s);

System.out.println(s); // 4:请问输出什么?

}

public static void change(String s) {

s = s+"def";

}

public static void change(int a) {

a = a + 10;

}

public static void change(Student s) {

s = new Student("李四",14);

}

public static void change1(Student s) {

s.setName("李四");

s.setAge(14);

}

}

大家看完上面的题目之后,估计有很多同学能回答出前两问,1:输出10, 2:输出abc,因为这类的参数传递在咱们java基础课程的第5天和第13天都有讲到。但是虽然讲了,但

是有很多同学都没有充分的理解透彻,这也就是为什么大家回答不出第三问和第四问的原因。实际上第三问的答案是3:输出Student [name=张三, age=13] 4:Student [name=李四, age=14]。下面我就给大家讲解一下。

首先用一句话来归纳java中参数传递:不管是基本类型还是引用类型:形式参数做赋值操作的时候,实际参数不发生改变,如果在方法里面是改变形式参数内部的一些东西的时候那么实际参数发生改变。 1. 不管是基本类型还是引用类型:形式参数做赋值操作的时候,实际参数不发生改变

(当被调用的方法开始执行的时候,就从方法区里面把方法拿到了栈内存中,形式参数变量也根据传递过

去的值进行初始化,当方法用完了,那么该方法在栈内存中的变量也消失了。在所以也就是只在栈内存

中对方法里面变量进行了改变,是不影响实际参数的。而加减乘除、赋值[就算是引用类型之间的赋值,是

不是也只是在栈内存中把地址值进行的赋值]这一系列的赋值操作都是在栈内存中对方法里面变量进行了改

变,而方法执行完毕后从栈内存中消失了,回到了调用这个方法的main方法栈内存中,实际参数原来是

什么现在依然是什么)

2. 如果在方法里面是改变形式参数内部的一些东西的时候那么实际参数发生改变

(对于引用类型,它随着参数传递到方法里面去的是地址值,指向的是堆中的对象,如果在方法里面通过

这个地址值改变对象内部的一些属性,即使方法用完了,方法里面的变量的地址值的

指向也消失了,但是

对象内部的一些属性还是已经改变了,这些属性不会消失[因为在堆内存中],所以实际参数还是会改变。如

果是基本类型,根本在堆内存中没有指向,基本类型都在栈内存或者常量池[值更不能被改变]中,所以基本

类型形式参数的改变无论如何是改变不了实际参数的)

3. 看完上面的两句话和解释,相信大家还是觉得比较抽象,下面我给大家准备了一个代码案例,每一行代码都有对应的解释,看完下面的案例后估计大家就会真正的明白java中参数传递,参数改变时机的问题了

public class Demo2 {

public static void main(String[] args) {

int a = 10;

int b = 20;

System.out.println(a+" "+b);//10 20

change1(a,b);

//形式参数做赋值操作的时候,实际参数不发生改变

//基本类型一般都在栈内存中(所以堆内存中没有指向内部也就没有东西嘛),

//所以值能做一些加减乘除、赋值的操作,

//而做完了这些操作,就在占内存中消失了,所以不会影响实际参数

System.out.println(a+" "+b);//10 20

System.out.println("-------------------");

Student s = new Student();

System.out.println(s);//Student [name=null, age=0]

change2(s);//详见方法内部注释

//如果在方法里面是改变形式参数内部的一些东西的时候那么实际参数发生改变System.out.println(s);//Student [name=hehe, age=1]

System.out.println("-------------------");

String string = "abc";

System.out.println(string);//abc

change3(string);//详见方法内部注释

//形式参数做赋值操作的时候,实际参数不发生改变

System.out.println(string);//abc

System.out.println("-------------------");

StringBuffer sb = new StringBuffer("hello");

System.out.println(sb);//hello

change4(sb);//详见方法内部注释

//如果在方法里面是改变形式参数内部的一些东西的时候那么实际参数发生改变

System.out.println(sb);//helloworld

System.out.println("-------------------");

int[] arr ={1,2,5,8,4,3};

System.out.println(Arrays.toString(arr));//[1, 2, 5, 8, 4, 3]

change5(arr,0,1);//详见方法内部注释

//如果在方法里面是改变形式参数内部的一些东西的时候那么实际参数发生改变

System.out.println(Arrays.toString(arr));//[2, 1, 5, 8, 4, 3]

Arrays.sort(arr);

System.out.println(Arrays.toString(arr));//[1, 2, 3, 4, 5, 8]

System.out.println("-------------------");

StringBuffer sb1 = new StringBuffer("abcd");

StringBuffer sb2 = new StringBuffer("efgh");

change6(sb1,sb2);//详见方法内部注释

System.out.println(sb1);//abcd

//形式参数做赋值操作的时候,实际参数不发生改变

System.out.println("-------------------");

Student s1 = new Student("hehe",1);

Student s2 = new Student("haha",20);

change7(s1,s2);//详见方法内部注释

//形式参数做赋值操作的时候,实际参数不发生改变

System.out.println(s1);//Student [name=hehe, age=1]

}

private static void change7(Student s1, Student s2) {

//引用类型s1指向的是一个地址值,s2也是指向的地址值,那么把s2的地址值赋给了s1,这

时候s1指向的地址

//值改变了,而s1内部(堆内存)的东西改变了吗?没有啊,等这个方法调用完毕了,地址值的指向也都消失了,

//s1还是指向原来的地址值,原来的地址值内部(堆内存)的东西还是没有改变,所以赋值操作不会影响实际参数

s1=s2;

}

private static void change6(StringBuffer sb1, StringBuffer sb2) {

//引用类型sb1指向的是一个地址值,sb2也是指向的地址值,那么把sb2的地址值赋给了sb1,这时候sb1指向的地址

//值改变了,而sb1内部(堆内存)的东西改变了吗?没有啊,等这个方法调用完毕了,地址值的指向也都消失了,

//sb1还是指向原来的地址值,原来的地址值内部(堆内存)的东西还是没有改变,所以赋值操作不会影响实际参数

sb1=sb2;

}

private static void change5(int[] arr, int i, int j) {

//引用类型arr指向的其实是一个地址值,那么通过地址值将对象内部(堆内存)的值发生改变了,

//即使这个方法调用完毕了,s所代表的地址的指向消失了,那么对象的内部其实已经改变了,所以形式参数改变实际参数

int temp = arr[i];[/i]

[i] arr = arr[j];[/i]

[i] arr[j] = temp;[/i]

[i] }[/i]

[i] private static void change4(StringBuffer sb) {[/i]

[i] //引用类型sb指向的其实是一个地址值,那么通过地址值将对象内部(堆内存)的字符长度改变了,[/i]

[i] //即使这个方法调用完毕了,s所代表的地址的指向消失了,那么对象的内部其实已经改变了,所以形式参数改变实际参数[/i]

[i] sb.append("world");[/i]

[i] }[/i]

[i] private static void change3(String string) {[/i]

[i] //String也是一个引用类型,但是String的值是放在了常量池中,而且常量池中的值是不能被改变的[/i]

[i] //在方法里面这个string所代表的是常量池中值得地址值,那么我说string += "def"这句话在常量池中其实是这样的:“找有没有abcdef,如果有就把abcdef的地址值赋给string[/i]

[i] //如果没有就在常量池中创建一个abcdef 并把地址值赋给string”。然而当我方法用完了 string代表的地址值的指向也消失了,那么原来main方法中的string

也不发生改变[/i]

[i] string += "def";[/i]

[i] }[/i]

[i] private static void change2(Student s) {[/i]

[i] //引用类型s指向的其实是一个地址值,那么通过地址值将对象内部(堆内存)的属性改变了,[/i]

[i] //即使这个方法调用完毕了,s所代表的地址的指向消失了,那么对象的内部其实已经改变了,所以形式参数改变实际参数[/i]

[i] s.setName("hehe");[/i]

[i] s.setAge(1);[/i]

[i] }[/i]

[i] private static void change1(int a, int b) {[/i]

[i] int temp = a;[/i]

[i] a= b;[/i]

[i] b=temp;[/i]

[i] }[/i]

[i]}

当大家看完这个例子的时候,相信很多同学有一种恍然大悟的感觉,终于搞明白为什么参数

传递的时候,实际参数有什么改变有时候不改变。如果大家还有什么疑问需要一起交流,请

在下面直接给我留言就可以了,或者直接来济南黑马程序员找大山哥哥来咨询,我会亲自给

同学讲解

参数传递方式

引用在函数参数传递中的作用 传递参数有三种方法:1,传递对象本身。2,传递指向对象的指针。3,传递对象的引用。 (1)传值方式 ①传给被调用函数的是整型、长整型、浮点型或双精度型变量。被调用的函数得定义相应的变量为形参。 ②传给被调用函数的是结构变量。被调用函数得定义结构变量为形参。 ③传给被调用函数的是结构变量的成员。被调用函数得定义与该成员同类的变量为形参。 #include "stdio.h" ?#include ?main( ) ?{ ?void swap(int pt1,int pt2); ?int a,b; ?scanf("%d, %d", &a,&b); ?swap(a,b); ?printf("\n%d,%d\n",a,b); ?} ?void swap(int pt1,int pt2) ?{int p; p=pt1; pt1=pt2; pt2=p; } ?

#include "stdio.h" void swapint(); int a,b; void main() { a = 5, b = 10; swapint(); printf("%d\n%d\n",a,b); } void swapint() { int temp; temp=a; a=b; b=temp; } (2)传址方式 ①传给被调用函数的是变量的地址。被调用函数得定义指针变量为形参。 ②传给被调用函数的是数组的地址即数组名。被调用的函数得定义数组或指针变量为形参。 ③传给被调用函数的是函数的地址即函数名称。被调用函数得定义指向函

数的指针变量为形参。④传给被调用函数的是结构的地址。被调用函数得定义结构指针为形参。 #include "stdio.h" ?#include ?main( ) ?{ ?void swap(int *pt1,int *pt2); ?int a,b,*p1,*p2; ?scanf("%d, %d", &a,&b); ?p1=&a;p2=&b; ?swap(p1,p2); ?printf("\n%d,%d\n",a,b); ?} ?void swap(int *pt1,int *pt2) ?{int p; p=*pt1; *pt1=*pt2; *pt2=p; } #include "stdio.h" void swapint(int *a,int *b); void main() { int a = 5, b = 10;

Java中传值与传引用的三种情况

java传值与传引用的三种情况大家先看一个例子: public class Example{ String str=new String("good"); char[]ch={'a','b','c'}; public static void main(String args[]){ Example ex=new Example(); ex.change(ex.str,ex.ch); System.out.print(ex.str+" and "); System.out.print(ex.ch); } public void change(String str,char ch[]){ str="test ok"; ch[0]='g'; } } 看看输出结果? good and gbc java中没有了c++中这样的引用符号,也没像c#中那样提供了out与ref 那么它是怎么做的呢 做什么事情都要去除例外的东西,String类就是此类问题的一个特殊情况 为什么特殊呢?

因为它是一个引用类型,确执行的是值传递。这样说有些抽象,还是举个例子吧 值传递: class Str { public static void main(String[] args) { int i = 900; System.out.println(i); changeInt(i); System.Out.println(i); } public static void changeInt(int s) { s = 34234; } } 结果: 900 900 这就是所谓的值传递。i把自己的副本给了函数changeInt的形参,而在changeInt中虽然将s赋值34234。但是对原来的i值并没有影响,因为它所修改的只是i的copy品而已。

C#中方法的参数有四种类型

C#中方法的参数有四种类型 1. 值参数(不加任何修饰符,是默认的类型) 2. 引用型参数(以ref 修饰符声明) 3. 输出参数(以out 修饰符声明) 4. 数组型参数(以params 修饰符声明) 1. 值传递: 值类型是方法默认的参数类型,采用的是值拷贝的方式。也就是说,如果使用的是值类型,则可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值。 使用值类型的例子如:(下面的Swap()未能实现交换的功能,因为控制传递回调用方时不保留更改的值) using System; class Test { static void Swap(int x, int y) { int temp = x; x = y; y = temp; } static void Main() { int i = 1, j = 2; Swap(i, j); Console.WriteLine("i = {0}, j = {1}", i, j); } } /* * 输出结果为: i=1, j=2 * 未能实现Swap()计划的功能 */ 2. 引用传递(ref类型) ref关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。 2.1. 若要使用ref 参数,则方法定义和调用方法都必须显式使用ref关键字。 2.2. 传递到ref 参数的参数必须最先初始化。这与out 不同,out 的参数在传递之前不需要显式初始化。 2.3. 如果一个方法采用ref 或out 参数,而另一个方法不采用这两类参数,则可以进行重载。

相关实例如下: using System; class Test { static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; } static void Main() { int i = 1, j = 2; Swap(ref i, ref j); Console.WriteLine("i = {0}, j = {1}", i, j); } } /* * 引用类型实现了Swap()计划的功能: * 输出为: * i = 2, j =1 */ 3. 输出类型(out类型) out 关键字会导致参数通过引用来传递。这与ref 关键字类似。 与ref 的不同之处: 3.1. ref 要求变量必须在传递之前进行初始化,out 参数传递的变量不需要在传递之前进行初始化。 3.2. 尽管作为out 参数传递的变量不需要在传递之前进行初始化,但需要在调用方法初始化以便在方法返回之前赋值。 示例如下: using System; class Test { static void Swap(out int x, out int y) { //在这里进行了i和j的初始化

java中的值传递和引用传递

转载 原文地址:https://www.360docs.net/doc/b115301593.html,/clara/archive/2011/09/17/2179493.html Java中的值传递和引用传递 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。 Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。 如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值. 如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。 例: 1public class ParamTest { 2public static void main(String[] args){ 3/** 4 * Test 1: Methods can't modify numeric parameters 5 */ 6 System.out.println("Testing tripleValue:"); 7double percent = 10; 8 System.out.println("Before: percent=" + percent); 9 tripleValue(percent); 10 System.out.println("After: percent=" + percent); 11 12/** 13 * Test 2: Methods can change the state of object parameters 14 */ 15 System.out.println("\nTesting tripleSalary:"); 16 Employee harry = new Employee("Harry", 50000);

函数调用参数传递类型(java)的用法介绍.

函数调用参数传递类型(java)的用法介绍. java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清。 (一)基本数据类型:传值,方法不会改变实参的值。 public class TestFun { public static void testInt(int i){ i=5; } public static void main(String[] args) { int a=0 ; TestFun.testInt(a); System.out.println("a="+a); } } 程序执行结果:a=0 。 (二)对象类型参数:传引用,方法体内改变形参引用,不会改变实参的引用,但有可能改变实参对象的属性值。 举两个例子: (1)方法体内改变形参引用,但不会改变实参引用,实参值不变。 public class TestFun2 { public static void testStr(String str){ str="hello";//型参指向字符串“hello” } public static void main(String[] args) { String s="1" ;

TestFun2.testStr(s); System.out.println("s="+s); //实参s引用没变,值也不变 } } 执行结果打印:s=1 (2)方法体内,通过引用改变了实际参数对象的内容,注意是“内容”,引用还是不变的。 import java.util.HashMap; import java.util.Map; public class TestFun3 { public static void testMap(Map map){ map.put("key2","value2");//通过引用,改变了实参的内容 } public static void main(String[] args) { Map map = new HashMap(); map.put("key1", "value1"); new TestFun3().testMap(map); System.out.println("map size:"+map.size()); //map内容变化了 } } 执行结果,打印:map size:2 。可见在方法testMap()内改变了实参的内容。 (3)第二个例子是拿map举例的,还有经常涉及的是 StringBuffer : public class TestFun4 {

C++中函数调用时的三种参数传递方式

在C++中,参数传递的方式是“实虚结合”。 ?按值传递(pass by value) ?地址传递(pass by pointer) ?引用传递(pass by reference) 按值传递的过程为:首先计算出实参表达式的值,接着给对应的形参变量分配一个存储空间,该空间的大小等于该形参类型的,然后把以求出的实参表达式的值一一存入到形参变量分配的存储空间中,成为形参变量的初值,供被调用函数执行时使用。这种传递是把实参表达式的值传送给对应的形参变量,故称这种传递方式为“按值传递”。 使用这种方式,调用函数本省不对实参进行操作,也就是说,即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值。 [cpp]view plaincopy 1./* 2. pass By value 3.*/ 4.#include https://www.360docs.net/doc/b115301593.html,ing namespace std; 6.void swap(int,int); 7.int main() 8.{ 9.int a = 3, b = 4; 10. cout << "a = " << a << ", b = " 11. << b << endl; 12. swap(a,b); 13. cout << "a = " << a << ", b = " 14. << b << endl; 15.return 0; 16.} 17.void swap(int x, int y) 18.{ 19.int t = x; 20. x = y; 21. y = t; 22.}

如果在函数定义时将形参说明成指针,对这样的函数进行调用时就需要指定地址值形式的实参。这时的参数传递方式就是地址传递方式。 地址传递与按值传递的不同在于,它把实参的存储地址传送给对应的形参,从而使得形参指针和实参指针指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。 [cpp]view plaincopy 1.#include https://www.360docs.net/doc/b115301593.html,ing namespace std; 3.void swap(int*,int*); 4.int main() 5.{ 6.int a = 3, b = 4; 7. cout << "a = " << a << ", b = " 8. << b << endl; 9. swap(&a,&b); 10. cout << "a = " << a << ", b = " 11. << b << endl; 12. system("pause"); 13.return 0; 14.} 15.void swap(int *x,int *y) 16.{ 17.int t = *x; 18. *x = *y; 19. *y = t; 20.} 按值传递方式容易理解,但形参值的改变不能对实参产生影响。 地址传递方式虽然可以使得形参的改变对相应的实参有效,但如果在函数中反复利用指针进行间接访问,会使程序容易产生错误且难以阅读。

java参数传递(经典)

java参数传递(超经典) (2009-02-20 14:47:22)转载 分类:Java 标签:杂 谈 Java中的参数传递机制一直以来大家都争论不休,究竟是“传值”还是“传址(传引用)”,争论的双方各执一词,互不相让。不但“菜鸟”们一头雾水,一些“老鸟”也只知道结果却说不出所以然来。我相信看过下面的内容后,你就会明白一些。 先看基本类型作为参数传递的例子: public class Test1 { public static void main(String[] args) { int n = 3; System.out.println("Before change, n = " + n); changeData(n); System.out.println("After changeData(n), n = " + n); } public static void changeData(int nn) { n = 10; } } 我想这个例子大家都明白,基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的,输出的结果证明了这一点: Before change, n = 3 After changeData(n), n = 3 那么,我们现在来看看对象作为参数传递的例子,这也是大家争论的地方。public class Test2 { public static void main(String[] args) { StringBuffer sb = new StringBuffer("Hello "); System.out.println("Before change, sb = " + sb); changeData(sb); System.out.println("After changeData(n), sb = " + sb); } public static void changeData(StringBuffer strBuf) {

总结Java方法(函数)传值和传引用的问题

总结Java方法(函数)传值和传引用的问题 java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清。 (一)基本数据类型:传值,方法不会改变实参的值。 public class TestFun { public static void testInt(int i){ i=5; } public static void main(String[] args) { int a=0 ; TestFun.testInt(a); System.out.println("a="+a); } } 程序执行结果:a=0 。 (二)对象类型参数:传引用,方法体内改变形参引用,不会改变实参的引用,但有可能改变实参对象的属性值。 举两个例子: (1)方法体内改变形参引用,但不会改变实参引用,实参值不变。 public class TestFun2 { public static void testStr(String str){ str="hello";//型参指向字符串“hello” } public static void main(String[] args) { String s="1" ;

TestFun2.testStr(s); System.out.println("s="+s); //实参s引用没变,值也不变 } } 执行结果打印:s=1 (2)方法体内,通过引用改变了实际参数对象的内容,注意是“内容”,引用还是不变的。 import java.util.HashMap; import java.util.Map; public class TestFun3 { public static void testMap(Map map){ map.put("key2","value2");//通过引用,改变了实参的内容 } public static void main(String[] args) { Map map = new HashMap(); map.put("key1", "value1"); new TestFun3().testMap(map); System.out.println("map size:"+map.size()); //map内容变化了 } } 执行结果,打印:map size:2 。可见在方法testMap()内改变了实参的内容。 (3)第二个例子是拿map举例的,还有经常涉及的是 StringBuffer : public class TestFun4 {

深入了解C语言(函数的参数传递和函数使用参数的方法)

深入了解C语言(函数的参数传递和函数使用参数的方法) C语言生成的代码在执行效率上比其它高级语言都高.现在让我们来看看C语言生成的代码具体是什么样子的.当你看完本文对于C语言的了解一定会更深一步了. 本文通过一个个实际案例程序来讲解C语言. 研究案例一 工具: Turboc C v2.0,Debug,MASM v5.0,NASM 实例C程序: /* example1.c */ char ch; int e_main() { e_putchar(ch); } 目标内容:C语言调用函数的方法与细节 我们使用的C编译器是16位的Turboc C v2.0,它生成的是16位的代码,比较简单,方便我们来研究.同时我们也需要用到DOS下的DEBUG来进行反汇编.由于我们很多案例中的程序并不是完整的C程序,所以Turboc下的Tlink并不能为我们生成目标程序,所以我将使用MASM 中的link.exe,同时里面的https://www.360docs.net/doc/b115301593.html,也可以为我们把exe文件转换成bin文件. 这个程序没有main函数,我们用e_main来代替main函数.这样我们能避开C语言对main函数进行一系列处理的代码.同样,我们也用e_putchar()来代替我们平常使用的putchar().这里"e"的意思就是"example". 没有了main函数,我们的C程序就没有了入口,所以在开始编译这段C代码之前,我还得写几行简单的汇编代码,通过它来作为我们程序的入口. ; C程序的入口start.asm [BITS 16] [global start] [extern _e_main] start: call _e_main 按照C语言的习惯,所以C总的名词都要自动在前面加一个"_"下划线.所以,我们在C中的e_main函数,如果要在汇编中调用,就变成了_e_main函数.这段汇编代码只有一句:call _e_main,就是调用我们在C中的e_main函数

java参数是如何传递的

java参数是如何传递的 总的来说,计算机语言给子程序传递参数的方法有两种。第一种方法是按值传递(call-by-value )。这种方法将一个参数值(value )复制成为子程序的正式参数。这样,对子程序的参数的改变不影响调用它的参数。第二种传递参数的方法是引用调用(call-by-reference )。在这种方法中,参数的引用(而不是参数值)被传递给子程序参数。在子程序中,该引用用来访问调用中指定的实际参数。这样,对子程序参数的改变将会影响调用子程序的参数。你将看到,根据传递的对象不同,Java 将使用这两种不同的方法。 在Java 中,当你给方法传递一个简单类型时,它是按值传递的。因此,接收参数的子程序参数的改变不会影响到该方法之外。例如,看下面的程序: // Simple types are passed by value. class Test { void meth(int i,int j) { i *= 2;j /= 2; } } class CallByValue { public static void main(String args[]) { Test ob = new Test(); int a = 15,b = 20; System.out.println("a and b before call: " +a + " " + b); ob.meth(a,b); System.out.println("a and b after call: " +a + " " + b); } } 该程序的输出如下所示: a and b before call: 15 20 a and b after call: 15 20 可以看出,在meth( ) 内部发生的操作不影响调用中a和b的值。它们的值没在本例中没有变为30和10。 当你给方法传递一个对象时,这种情形就会发生戏剧性的变化,因为对象是通过引用传递的。记住,当你创建一个类类型的变量时,你仅仅创建了一个类的引用。因此,当你将这个引用传递给一个方法时,接收它的参数将会指向该参数指向的同一个对象。这有力地证明了对象是通过引用调用传递给方法的。该方法中对象的改变确实影响了作为参数的对象。例如,考虑下面的程序: // Objects are passed by reference. class Test { int a,b; Test(int i,int j) {a = i;b = j; } // pass an object void meth(Test o) {

SpringMVC向页面传递参数的4种方式

SpringMVC向页面传递参数的4种方式 1、使用HttpServletRequest和Session 然后setAttribute(),就和Servlet 中一样 request.setAttribute(“user”,user_data); 2、使用ModelAndView对象 @RequestMapping("/login.do") publicModelAndView login(String name,String pass) { User user = userService.login(name,pwd); Map data = new HashMap(); data.put("user",user); return newModelAndView("success",data); } 3、使用ModelMap对象 ModelMap数据会利用HttpServletRequest的Attribute传值到success.jsp中 @RequestMapping("/login.do") public String login(String name,String pass ,ModelMapmodelMap) { User user =userService.login(name,pwd); modelMap.addAttribute("user",user); modelMap.put("name",name); return "success"; } Session存储,可以利用HttpServletReequest的getSession()方法 @RequestMapping("/login.do") Public String login (String name,Stringpwd,ModelMapmodel,HttpServletRequest request) { User user = serService.login(name,pwd); HttpSession session = request.getSession(); session.setAttribute("user",user); model.addAttribute("user",user); return "success"; } 4、使用@ModelAttribute注解

java参数传递时到底是值传递还是引用传递

java参数传递时到底是值传递还是引用传递(baidu搜集) 最近比较长一段时间以来,网上的IT同行里面比较流行“JAVA面试32问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解。 原题是:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 用google查询结果,得到答案基本上是:值传递。当时觉得挺纳闷儿,为什么连参数的内容都被修改了,怎么还能说是“值传递”呢?因为在传统的印象里(尤其是从C++过来以后),值传递都应该是不改变原参数的。 问问周围的同事,也大都这么讲,但是也都讲不清这种理论的根源是什么。我这个人有个毛病,有事情想不通时就会憋得难受,后来在《Thinking in Java》的一段内容(注解[1])里找到了自己的结论,我认为(《Thinking in Java》的作者也这么认为):可以说是值传递,也可以说是引用传递。 一,认为是值传递。得出这种结论的前提必须是“参数的值就是对该对象的引用,而不是对象的内容”,这句话可能有些费解,举个例子加以说明。 public class Paier { public static void main(String[] args) { Paier paier = new Paier(); paier.test();

} public void test() { TestClass para1 = new TestClass(); para1.setTest(new Integer(10)); TestClass result1 = test1(para1); System.out.println("para1 = " + para1.getTest()); System.out.println("result1 = " + result1.getTest()); TestClass para2 = new TestClass(); para2.setTest(new Integer(10)); TestClass result2 = test2(para2); System.out.println("para2 = " + para2.getTest()); System.out.println("result2 = " + result2.getTest()); } public TestClass test1(TestClass t) {

Java值传递和引用

java语言深入(java中是传值还是引用) 关键字: java基础深入 熟悉C的程序员都用过指针,对指针可谓爱之深恨之切。指针是指向一块内存地址的内存数据(有些拗口),也就是说指针本身是一个占用4字节内存的int(32 位系统内),而这个int值恰恰又是另一块内存的地址。比如"hello"这个字串,存放在@0x0000F000这个地址到@0x0000F005这段内存区域内(包括0x00的结束字节)。而在@0x0000FFF0到@0x0000FFF03这四个字节内存放着一个int,这个int的值是@0x0000F000。这样就形成了一个指向"hello"字串的指针。 在Java中,很多人说没有指针,事实上,在Java更深层次里,到处都是大师封装好的精美绝伦的指针。为了更容易的讲解Java 中关于类和类型的调用,Java中出现了值与引用的说法。浅显的来说,我们可以认为Java中的引用与C中的指针等效(其实差别非常非常大,但是为了说明我们今天的问题,把他们理解为等效是没有任何问题的)。 所谓传引用的说法是为了更好的讲解调用方式。基于上面对指针的理解,我们不难看出,指针其实也是一个int值,所谓传引用,我们是复制了复制了指针的int值进行传递。为了便于理解,我们可以姑且把指针看作一种数据类型,透明化指针的int特性,从而提出传引用的概念。 重申一遍:Java中只有传值。 1所谓传值和传引用 传值和传引用的问题一直是Java里争论的话题。与C++不同的,Java里面没有指针的概念,Java的设计者巧妙的对指针的操作进行了管理。事实上,在懂C++的Java程序员眼中,Java到处都是精美绝伦的指针。 下面举个简单的例子,说明什么是传值,什么是传引用。 //例1 void method1(){ int x=0; this.change(x); System.out.println(x); } void int change(int i){ i=1; } 很显然的,在mothod1中执行了change(x)后,x的值并不会因为change方法中将输入参数赋值为1而变成1,也就是说在执行change(x)后,x的值z依然是0。这是因为x传递给change(int i)的是值。这就是最简单的传值。 同样的,进行一点简单的变化。 //例2 void method1(){ StringBuffer x=new StringBuffer("Hello"); this.change(x); System.out.println(x); }

java对象、数组作为参数传递,静态变量、静态方法的使用,内部类,使用文档注释

java学习笔记(四)----对象、数组作为参数传递,静态变量、静态方法的使用,内部类,使用文档注释 2009-10-15 20:21 ***对象作为参数传递*** class passparam { int x; public static void main(String[] args) { passparam obj = new passparam(); obj.x=5; change(obj); System.out.println(obj.x); //如果change方法不是静态的,想调用它就得写成new passparam().change(obj); } public static void change(passparam obj) //如果这个函数前面没加static编译出错,因为非静态方法,不能被静态方法直接调用,main 是一个静态方法。 { obj.x=3;} } 结果:3 ***数组作为参数传递*** class passparam { int x; public static void main(String[] args) { passparam obj = new passparam(); int []x=new int[1]; x[0]=5; change(x); System.out.println(x[0]); } public static void change(int[] x) { x[0]=3; } } 结果:3 ***静态变量、静态方法的使用*** 静态变量相当于全局变量 class Chinese { static string country="中国"; //如果改为private static string country="中国" 下面的两处调用,就会出错 String name; int age; static void sing() { System.out.println("啊~~") void singOurCountry() { System.out.println(country); sing(); } }

关于JAVA中参数地址传递的问题

public class Test5 { public static void main(String[] args) { int [] a = { 1, 2, 3, 4, 5 }; int [] b = new int [a.length ]; System.out .println("交换前:"); print (a); print (b); b = swap (a); System.out .println("交换后:"); print (a); print (b); } private static void print(int [] a) { for (int i = 0; i < a.length ; i++) { System.out .print(" " + a[i]); } System.out .println(); } private static int [] swap(int [] c) { int [] tmp = new int [c.length ]; for (int j = 0; j < c.length ; j++) { tmp[j] = c[c.length - j - 1] + 10; } return tmp; } } 结果: 交换前: 1 2 3 4 5 0 0 0 0 0 交换后: 1 2 3 4 5 15 14 13 12 11 说明: 在该程序中,在调用swap()方法时,,数组a 将其地址传递给数组c ,所以a 和c 是指向同一个数组。 但在swap 方法中,新生成了一个数组tmp,改变是在tmp 数组上进行的.返回时把tmp 数组的首地址送数组b.所以b 指向改变后数组tmp. public class Test5 { public static void main(String[] args) { int [] a = { 1, 2, 3, 4, 5 }; int [] b = new int [a.length ]; System.out .println("交换前:"); print (a); print (b); b = swap (a); System.out .println("交换后:"); print (a); print (b); } private static void print(int [] a) { for (int i = 0; i < a.length ; i++) { System.out .print(" " + a[i]); } System.out .println(); } private static int[] swap(int [] c) { for (int j = 0; j < a.length ; j++) { c[j] = c[c.length - j - 1] + 10; } return c ; } } 结果: 交换前: 1 2 3 4 5 0 0 0 0 0 交换后: 15 14 13 24 25 15 14 13 24 25 说明: 在该程序中,在调用swap()方法时,数组a 将其地址传递给数组c ,所以a 和c 是指向同一个数组。 返回时,数组b 不再指向原来的数组,而指向c 所在的数组。 注: JAVA 中参数传递时是值传递,引用型与基本数据类型是不同的. 1 2 3 4 5 15 14 13 12 11 a[ ] c[ ] 0 0 0 0 0 b[ ] a[ ] c[ ] b[ ] 1 2 3 4 5 1 2 3 4 5 a[ ] c[ ] 0 0 0 0 0 b[ ] a[ ] c[ ] b[ ] 15 14 13 12 11

java中的值传递和引用传递

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。(参数类型为基本数据类型) 引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。(类和数组) 下面举例说明: 传值---传递基本数据类型参数 public class PassValue{ static void exchange(int a, int b){//静态方法,交换a,b的值 int temp; temp = a; a = b; b = temp; } public static void main(String[] args){ int i = 10; int j = 100; System.out.println("before call: " + "i=" + i + "\t" + "j = " + j);//调用前 exchange(i, j); //值传递,main方法只能调用静态方法 System.out.println("after call: " + "i=" + i + "\t" + "j = " + j);//调用后 } } 运行结果: before call: i = 10 j = 100 after call: i = 10 j = 100 说明:调用exchange(i, j)时,实际参数i,j分别把值传递给相应的形式参数a,b,在执行方法exchange()时,形式参数a,b的值的改变不影响实际参数i和j的值,i和j的值在调用前后并没改变。 引用传递---对象作为参数 如果在方法中把对象(或数组)作为参数,方法调用时,参数传递的是对象的引用(地址),即在方法调用时,实际参数把对对象的引用(地址)传递给形式参数。这是实际参数与形式参数指向同一个地址,即同一个对象(数组),方法执行时,对形式参数的改变实际上就是对实际参数的改变,这个结果在调用结束后被保留了下来。 class Book{ String name; private folat price; Book(String n, float ){ //构造方法 name = n; price = p; } static void change(Book a_book, String n, float p){ //静态方法,对象作为参数 a_https://www.360docs.net/doc/b115301593.html, = n;

PHP页面间参数传递的四种方式

PHP 页面间参数传递的四种方式
分类: 网络文摘 2011-12-15 18:34 20269 人阅读 评论(12) 收藏 举报 phpsession 浏览器 inputaction 服务器
我们定义 page01.php 和 page02.php 两个 php 文件,将 page01 中的 内容想办法传递到 page02,然后供我们继续使用。
第一种: 使用客户端浏览器的 cookie。cookie 很容易理解,就是一个临时文件, 可以把它看成一个储藏室,浏览器在浏览的过程中记录一些信息,就暂 时存放在这里。 在 page01 中设置一个 cookie。 就是这么简单,我们已经创建 cookie 完毕。 我们定义了一个变量 mycookie,它的值是字符串'自灵'。 我们可以随便给 cookie 变量起名字,可以定义多个 cookie 变量。
在 page02 页面接受 cookie。

我们使用$_COOKIE[]提取 cookie 中的变量 mycookie,将它的值付给 $wuziling。然后简单的输出。 好了,到这里使用 cookie 从页面之间传递参数完毕。
第二种: 使用服务器端的 session。 理解 session 是一件很容易的事情。 与 cookie 的不同在于它是服务器端的临时储藏室。session 常被称作会话。 在 page01 中设置一个 session。 要想使用 session, 必须启动 session。 session_start();就是启动 session 的方法。一般要写在最前面。 第二个语句我定义了一个$_SESSION["temp"]数组,数组的名称是 $_SESSION["temp"],里面存储了 3 个字符串。 在 page02 页面接受 session。 '; } ?> 首先启动会话。启动后我们在 page01 定义的变量已经可以使用了,不 需要其他任何获取的操作,这里不同于 cookie。

相关文档
最新文档