java值传递和引用传递

  相信对不少初学java的人来讲这部份内容不太容易明白,最近又看了一些java视频,有点收获,打算总结一下。java明确说明取消了指针,由于指针每每是再带来方便的同时也是致使代码不安全的根源,并且还会使得程序变得很是复杂和难以理解。java放弃指针只是在java语言中没有明确的指针定义,实质上,每个new语句返回的都是一个指针的引用。只不过在大多数时候java不用关心如何操做这个“指针”,更不像在操做C++的指针那样胆战心惊,惟一要多注意的是在给函数传递对象的时候。因此,初学java的人没必要花费太多精力去了解,可是对于一个真正的java程序员来讲这个问题是基础。废话少说,直接进入正题:
java中是传值仍是传引用呢 ?
  关于这个问题,就像光究竟是波仍是粒子的问题同样众说纷纭。可是咱们首先要搞清楚一点:无论java的参数类型是什么,一概传递参数的副本(引用thinking in Java 中的一句话:When you're passing primitives into a method, you get a distinct copy of the primitive.When you're passing a reference into a method, you get a copy of the reference)。
java中的变量分为如下两类:
  (1)基本类型变量(int,long,double,boolean,float, byte,char),对于这些变量,java传递的是值的副本(与c++相同),即把本身赋值一份传递,即便本身的副本变了,本身也不会改变;
  (2)对象型变量。java传递的是引用的副本(复制指向地址的指针),而不是本身实际值的副本。为啥这么作呢?缘由很简单,由于对象类型是放在堆里边的(new一个对象的时候其实是再堆中开辟出了一块内存空间存放对象,在栈中存放指向对象的指针),因此访问位于堆中的对象相对于基本类型数据来讲比较慢;另外一方面是由于对象类型自己就比较大,若是采用复制对象值的方法,不只浪费内存并且速度比较慢。
在thinking in Java 中解释是这样的:不论是基本类型仍是对象类型,都是传值。这种说法是把引用的副本也看做了一种“值”,也可以说的过去,可是本人仍是更同意将按值传递和按引用传递分开比较好理解。
注意:java中String类型也是对象型变量,因此它传递的是引用的副本。String是一个非可变类,其传值仍是传引用显得没什么区别。html

理论说完了,下面看几个例子:
num1:传基本类型
java

public class Test {

public static void test(boolean test) {
test = !test;
System.out.println("In test(boolean):test = " + test);
}

public static void main(String args[]) {
boolean test = true;
System.out.println("Before test(boolean):test = " + test);
test(test);
System.out.println("After test(boolean):test = " + test);
}

}

 

运行结果:
Before test(boolean):test = true
In test(boolean):test = false //传进去的是boolean类型的副本,副本改变了可是原值不改变
After test(boolean):test = true
num2:传对象类型node

public class Test {

public static void test(StringBuffer str) {
str.append(", World!");
}

public static void main(String args[]) {
StringBuffer string = new StringBuffer("Hello");
test(string);
System.out.println(string);
}

}

 

运行结果:Hello, World! //经过引用副本找到地址,而后修改里边的值,即修改了对象。
num3:关于传Stringc++

public class Test {

public static void test(String str) {
str = "World";
}

public static void main(String args[]) {
String string = "Hello";
test(string);
System.out.println(string);
}

}

一眼看去输出结果应该是:World程序员

可是实际的运行结果倒是:Hello,String不是按引用传递的吗?难道出问题了?
翻看了一些java教程,缘由以下:
  执行str = “World”;这句的时候,系统会自动生成一个新的String对象,并把这个新对象的值设为“World”,而后将这个对像的引用赋值给str,str是原来String的副本,改变的是副本的值,那么就与原来的值没有关系了。当test函数执行完毕,str随之释放,原来的内存地址上内容没发生任何变化。所以输出hello,num2中str.append(", World!");就不同了,StringBuffer是产生一块内存空间,相关的增、删、改操做都在其中进行,因此此句是在同一段内存上进行的,即修改了原值,str所指向的引用并无变。
安全

相关文章
相关标签/搜索