1、javascript中的参数传递:值传递
(1)在js函数传递中,当基本类型(number, string, boolean, null, undefined, symbol)变量作为参数传递时,函数内部对参数的任何操作都不会改变变量的值。
(2)当object类型变量作为参数传递时,函数内部对参数的操作会影响变量的值,除非函数内部对参数重新赋值(任何类型的值)。
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8"/>
</head>
<body>
<p>welcome </p>
<script language="JavaScript">
var obj = {};
obj.inner = 10;
var num = 10;
var str = 'Hello';
var boo = true;
var oth = null;
var und = undefined;
var sym = Symbol('foo');
function passingobject(myobj){
myobj.inner = 1+myobj.inner;
}
function passingvalue(myValue){
switch (typeof myValue){
case 'number':
myValue = myValue+1;
break;
case 'string':
myValue = 'I am a new string now!';
break;
case 'boolean':
myValue = false;
break;
default :
case 'number':
myValue = 'Null,Undefined,or Symbol';
}
}
console.log("before num"+num);//10
passingvalue(num);
console.log("after num"+num);//10
console.log("before str = " + str); // before str = Hello
passingvalue(str);
console.log("after str = " + str); // after str = Hello
console.log("before boo = " + boo); // before boo = true
passingvalue(boo);
console.log("after boo = " + boo); // after boo = true
console.log("before oth = " + oth); // before oth = null
passingvalue(oth);
console.log("after oth = " + oth); // after oth = null
console.log("before und = " + und); // before und = undefined
passingvalue(und);
console.log("after und = " + und); // after und = undefined
console.log(sym); // Symbol(foo)
passingvalue(sym);
console.log(sym); // Symbol(foo)
console.log("before obj.inner = " + obj.inner); //www.baiyuewang.net before obj.inner = 10
passingobject(obj); // after obj.inner = 11
console.log("after obj.inner = " + obj.inner);
function changeStuff(a, b, c)
{
a = a * 10;
b.item = "changed";
c = {item: "changed"};
}
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
console.log(obj1.item);//unchanged
console.log(obj2.item); // unchanged
console.log(num);//10
changeStuff(num, obj1, obj2);
console.log(num);//10
console.log(obj1.item); // changed
console.log(obj2.item); // unchanged
</script>
</body>
</html>
2、java中的参数传递:值传递
(1)对于基本类型变量作为参数传递时,java是传递值的副本,函数内部对参数的任何操作都不会改变变量的值。
(2)对于一切对象型变量,java都是传递引用的副本,函数内部对参数的操作会影响变量的值,除非函数内部对参数重新赋值(任何类型的值)。 要注意String类型,因为属于final类型,所以总是不会被影响
package com.shenzhoufu;
import java.util.*;
public class Reference {
public static void main(String[] args){
//————————boolean——————————————————————————————
boolean b = true;
System.out.println("unchanged:"+b);//true
testBoo(b);//false
System.out.println("changed:"+b);//true
//————————String——————————————————————————————
String str = ",world!";
System.out.println("unchanged:"+str);//,world!
testString(str);//Hello
System.out.println("changed:"+str);//,world!
//————————————StringBuffer——————————————————————
StringBuffer strb = new StringBuffer(",world!");
System.out.println("unchanged:"+strb);//,world!
testStringBuffer(strb);//,world!hello
System.out.println("changed:"+strb);//,world!hello
}
//基本类型
public static void testBoo(boolean b){
b = !b;
System.out.println("changing(in test):"+b);
}
//String类型
public static void testString(String s){
String string = "Hello";
System.out.println("newString:"+string);
}
//StringBuffer 对象
public static void testStringBuffer(StringBuffer s){
s.append("hello");
System.out.println("changing(in test)StringBuffer:"+s);
}
}
1、对象是按引用传递的
2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
class Test01
{
public static void main(String[] args)
{
StringBuffer s= new StringBuffer("good");
StringBuffer s2=s;
s2.append(" afternoon.");
System.out.println(s);
}
}
对象s和s2指向的是内存中的同一个地址因此指向的也是同一个对象。
如何解释“对象是按引用传递的”的呢?
这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的,有问题吗?
程序运行的输出是:
good afternoon.
这说明s2和s是同一个对象。
这里有一点要澄清的是,这里的传对象其实也是传值,因为对象就是一个指针,这个赋值是指针之间的赋值,因此在java中就将它说成了传引用。(引用是什么?不就是地址吗?地址是什么,不过就是一个整数值)
class Test2
{
public static void main(String[] args)
{ StringBuffer s= new StringBuffer("good");
StringBuffer s2=new StringBuffer("bad");
test(s,s2);
System.out.println(s);// goodhah
System.out.println(s2);//bad为什么呢????有大神能解释么
}
public static void test(StringBuffer s,StringBuffer s2) {
System.out.println(s);//good
System.out.println(s2);//bad
s2=s;
s=new StringBuffer("new");
System.out.println(s);//new
System.out.println(s2);//good
s.append("hah");
s2.append("hah");
System.out.println(s);//newhah
System.out.println(s2);//goodhah
}}
——————————————————————————————————————————————————
不同的操作系统不太一样,但一般内存都分为4个区域:
1)heap(堆):存放new出来的对象
2)stack(栈):存放局部变量
3)data segment(数据区):静态变量 和 字符串常量
4)code segment(代码区):存放代码
Java中进行方法调用的时候传递参数时,遵循值传递的原则:
1)基本数据类型,传递的是数据的拷贝
2)引用数据类型,传递的是传递的引用地址的拷贝,而不是该对象本身
例子:
public class Test {
void f(int j) {
System.out.println(j);
}
void ff(String ss) {
System.out.println(ss);
}
public static void main(Stirng[] args) {
int i = 100;
String s = "hello";
Test t = new Test();
t.f(i);
t.ff(s);
}
}
内存中的执行过程:
当mian方法开始执行的时候
(1)int i = 100; 栈中分配一块空间,存放变量i,值为100,基本数据类型只占一块空间;
(2)String s = "hello"; "hello"是字符串常量,分配在data区,字符串常量为String类的一个对象,s指向了这个"hello"对象,这就是引用数据类型,在内存中占两块空间;有点形象思维:一提引用类型,就是一块内存指向另一块内存s可以被叫做:引用、引用变量、引用地址,其实s就是一个指针,在这里不用钻牛角尖,你就知道s是一个引用,s的值是一个地址,根据这个地址就可以找到一个对象就ok了
(3)Test t = new Test(); 同理,栈中的引用t指向了堆中new出来的这个Test对象;
(4)t.f(i); 方法的形参属于局部变量,所以在调用f方法的时候,栈内存分配一个int型的变量j,将i的值当做实参传递过去,i的值是100,现在将100拷贝给了j,那么j的值就是100,这就是楼主说的“值传递”,接着打印,最后方法结束,为该方法分配的局部变量立刻全部清空,那么Stack中这个j消失了;
(5)t.ff(s); 调用ff方法的时候,栈内存分配一个String型的变量ss,将s的值当做实参传递过去,s指向了"hello"对象,s的值是一个地址,现在将这个地址拷贝给了ss,那么ss也就指向这个"hello"了这就是楼主说的"引用传递",现在s 和 ss 两个引用 同时指向了"hello"对象,然后打印ss,最后方法结束,栈中这个ss被清除;
现在main方法执行结束,为main方法分类的局部变量清除,i,s,t全部消失,data区的符串常量"hello"和堆内存的Test对象,由于没有任何引用指向他们了,就会被垃圾收集器回收