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

java参数传递时到底是值传递还是引用传递
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) {

t = new TestClass();

t.setTest(new Integer(20));

return t;

}

public TestClass test2(TestClass t) {

t.setTest(new Integer(20));

return t;

}

class TestClass {

Integer test = null;

public void setTest(Integer i) {

test = i;

}

public Integer getTest() {

return test;

}

}

}

执行后的结果是:

para1 = 10

result1 = 20

para2 = 20

result2 = 20

为什么会这样呢?因为test1想通过修改参数的引用来修改返回值,但是在JAVA中,参数的引用是不可修改的,所以para1和result1分别指向不同的空间,结果也不一样。而在test2中,result2和para2始终指向同一块区域,test2方法修改的是参数内容,而不是参数的引用。

从上面看来,因为参数的引用不可改变,如果理解为“参数的值就是对该对象的引用”,那么java自然只有值传递。

二,认为是引用传递。还是上面的例子,如果在参数传递时理解为“参数的值就是该对象的内容”,那么显然不是值传递,因为对象的内容已经改变了。

认为是引用传递还有一个理由,就是java有一个保留字byvalue,现在的JDK 版本中还没有实现这个保留字,似乎是在暗示对这种观点的支持。(There appears to be some support for this view within Sun, since one of the

“reserved but not implemented” keywords is byvalue.)

所以说,对于原题的结论,是值传递还是引用传递并不重要,重要的是要理解“对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。”

注解[1]:下面是在《Thinking in Java》中的原文:

This brings up the terminology issue, which always seems good for an argument.The term is “pass by value,” and the meaning depends on how you perceive the operation of the program. The general meaning is that you get a local copy of whatever you’re passing, but the real question is how you think about what you’re passing. When it comes to the meaning of “pass by value,” there are two fairly distinct camps:

1.Java passes everything by value. When you’re passing primitives into

a method, you get a distinct copy of the primitive. When you’re passing a handle into a method, you get a copy of the handle. Ergo, everything is pass by value. Of course, the assumption is that you’re always thinking (and caring) that handles are being passed, but it seems like the Java design has gone a long way toward allowing you to ignore (most of the time) that you’re working with a handle. That is, it seems to allow you to think of the handle as “the object,” since it implicitly dereferences it whenever you make a method call.

2.Java passes primitives by value (no argument there), but objects are passed by reference. This is the world view that the handle is an alias for

the object, so you don’t think about passing handles, but instead say “I’m passing the object.” Since you don’t get a local copy of the object when you pass it into a method, objects are clearly not passed by value. There appears to be some support for this view within Sun, since one of the “reserved but not implemented” keywords is byvalue. (There’s no knowing, however, whether that keyword will ever see the light of day.)

Having given both camps a good airing and after saying “It depends on how you think of a handle,” I will attempt to sidestep the issue for the rest of the book. In the end, it isn’t that important – what is important is that you understand that passing a handle allows the caller’s object to be changed unexpectedly.

参数传递方式

引用在函数参数传递中的作用 传递参数有三种方法: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/874200865.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/874200865.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/874200865.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/874200865.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的数据传输设计的实验报告 高灵琪 1110230015

基于java的数据传输设计的实验报告 基于Java和OPC技术的分布式远程监控系统,系统的结构模型如图1所示。系统的功能是:实现对生产过程的数据采集和存贮,并在远程客户端实现对采集过程的监测和控制。 1.介绍 系统采用多层Client/Server结构。总体上可以分为3个层次:数据服务器层、应用服务器层和客户端。数据服务器负责提供所需的数据,包括系统的实时数据、历史数据和报警信息等;应用服务器接收客户端发出的请求信息,根据客户端的请求与数据服务器进行交互,实现客户端的请求。客户端负责数据曲线的显示,并负责处理用户的监控请求。 2.1系统中的数据传送问题 本系统采用分布式技术,应用服务器和远程客户端分别位于网络中不同的主机上,采集的数据用RMI技术通过网络从服务器端传送到客户端。 系统中,客户端需要完成两项任务,一是对采集过程的监测和控制,并用波形图把采集的数据实时地显示在客户端界面上,这就要求数据采集服务器采集的数据实时的传送到客户端,保证监控的实时性。客户端的另一项任务是,把从服务器端传送过来的数据保存在客户端计算机上,以便用户能浏览和分析采集到的数据。为保证对数据分析的正确和完整,数据采集服务器采集的数据应全部传送到客户端,这就要求数据传送的准确性,即数据应无丢失的在网络上进行传送。总之,数据从服务器端传送到远程客户端时,应满足数据传送的实时性和准确性。 然而,当数据在网络上进行传送时,由于网络的连接情况和拥塞情况具有一定的随机性,很多时候会出现网络抖动的情况,造成客户端与服务器端失去连接,使数据传送中断。为保证数据传送的实时性和准确性,需采取措施,当网络连接出现短时断开的时候,客户端和服务器端应能自动重新建立连接,使实时监控和数据保存继续进行。对于由于网络短时中断时没能传送的数据,应采用缓存的方法,待连接重新建立后,再把这些数据进行传送。 3.1数据传送方案及数据缓存的实现 如前所述,客户端需要完成两项任务:一是对数据采集进行实时监控,二是把从服务器端传送过来的数据保存在客户端计算机上。在这两项任务中,实时监控任务要求保证数据的实时性,即服务器端采集的数据应实时地传送到客户端,让用户及时了解数据采集的情况。而数据保存任务需要的是数据传送的准确和完整,即采集的数据应无丢失的从服务器端传送到客户端。考对传送的要求,为保证他们都能满足各自的功能,本系统在设计数据传送时,把实时监控部分和数据保存部分分开,即分别通过不同的途径从服务器端获得数据。 对数据保存部分,采用在服务器端先用数组缓存数据,缓存数组中的数据达到一定数量后,由服务器主动一次性把这些数据传送到客户端。具体的方法是:在服务器端,对每一通道的数据先用两个数组交替进行缓存,数据采集服务器传送过来的数据先放进数组1,当数据满一定数量后(例如200个),由数组 2接着接收数据,与此同时,新开一个线程,把数组中的数据通过远程方法调用主动传送给客户端。在传送数组时如果网络是中断的,则可利用后面介绍的重连接机制,让客户和服务器重新建立连接,只要在数组2接收200个数据的过程中,连接能够重新建立,把数组1传送成功,就可以保证数据无丢失的传送。这就是本远程监控系统在网络短时中断时,利用数组对数据进行缓存的原理所在。数组2接收满200个数据后,新开一个线程传送数组2,同时由数组1

关于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/874200865.html, = n;

相关文档
最新文档