我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
Java 通过值的参数,并且仅值。
短篇小说 短篇小说:
对于来自C#的人来说:没有“外”参数,对于来自PASCAL的人来说:没有“存在”参数。
这意味着你不能从对象本身改变参考,但你总是可以改变对象的属性。
一个工作室是使用 StringBuilder 参数而不是 String。
其他回答
正如许多人之前提到的那样,Java总是有价值的。
下面是另一个例子,这将帮助你理解差异(经典交换例子):
public class Test {
public static void main(String[] args) {
Integer a = new Integer(2);
Integer b = new Integer(3);
System.out.println("Before: a = " + a + ", b = " + b);
swap(a,b);
System.out.println("After: a = " + a + ", b = " + b);
}
public static swap(Integer iA, Integer iB) {
Integer tmp = iA;
iA = iB;
iB = tmp;
}
}
印刷:
前: a = 2, b = 3 后: a = 2, b = 3
这是因为 iA 和 iB 是新的本地参考变量,具有相同值的过去参考(他们的点到 a 和 b 相应)。因此,试图改变 iA 或 iB 的参考将仅在本地范围内变化,而不是在该方法之外。
我做了这个小图表,显示了数据是如何创建和通过的
此分類上一篇
注意:原始值作为值传递,该值的第一个参考是方法的论点。
这意味着:
您可以在函数内更改 myObject 的值 但您不能更改 myObject 引用到,函数内,因为点不是 myObject 记住,点和 myObject 是引用,不同引用,但是,这些引用在同一个新点(0,0)
在我所知道的范围内,Java只知道值的呼叫,这意味着对于原始数据类型,您将使用复印件工作,对于对象,您将使用对象的参考复印件工作。
public static void swap(StringBuffer s1, StringBuffer s2) {
StringBuffer temp = s1;
s1 = s2;
s2 = temp;
}
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("Hello");
StringBuffer s2 = new StringBuffer("World");
swap(s1, s2);
System.out.println(s1);
System.out.println(s2);
}
这将人口Hello World而不是World Hello,因为在交换函数中,您使用复印件,这些复印件不会对主要的参考产生影响。
public static void appendWorld(StringBuffer s1) {
s1.append(" World");
}
public static void main(String[] args) {
StringBuffer s = new StringBuffer("Hello");
appendWorld(s);
System.out.println(s);
}
如果您将 StringBuffer 更改为 String,它只会产生 Hello 因为 String 是不可变的。
public static void appendWorld(String s){
s = s+" World";
}
public static void main(String[] args) {
String s = new String("Hello");
appendWorld(s);
System.out.println(s);
}
但是,你可以为 String 做一个插槽,这将使它能够与 Strings 一起使用:
class StringWrapper {
public String value;
public StringWrapper(String value) {
this.value = value;
}
}
public static void appendWorld(StringWrapper s){
s.value = s.value +" World";
}
public static void main(String[] args) {
StringWrapper s = new StringWrapper("Hello");
appendWorld(s);
System.out.println(s.value);
}
编辑:我认为这也是使用 StringBuffer 的理由,当涉及到“添加”两个线条时,因为你可以修改原始对象,你不能用像 String 这样的不可变的对象。
在所有的答案中,我们看到Java通过价值,或者正如Gevorg所写的那样:“通过复制变量的价值”,这就是我们应该始终记住的想法。
在Java中,你总是通过复制论点,即你总是在函数中创建一个新的值例子,但有些行为会让你认为你正在通过参考。
此分類上一篇: [ref 1]
void incrementValue(int inFunction){
inFunction ++;
System.out.println("In function: " + inFunction);
}
int original = 10;
System.out.print("Original before: " + original);
incrementValue(original);
System.out.println("Original after: " + original);
We see in the console:
> Original before: 10
> In Function: 11
> Original after: 10 (NO CHANGE)
以 [ref 2] 的例子
顯示優雅的機制觀點 max 5 min
(按参考通行) pass-by-copy-of-the-variable-值
void incrementValu(int[] inFuncion){
inFunction[0]++;
System.out.println("In Function: " + inFunction[0]);
}
int[] arOriginal = {10, 20, 30};
System.out.println("Original before: " + arOriginal[0]);
incrementValue(arOriginal[]);
System.out.println("Original before: " + arOriginal[0]);
We see in the console:
>Original before: 10
>In Function: 11
>Original before: 11 (CHANGE)
复杂物体本身正在复制,但内部参考正在保持。
此分類上一篇: [ref 3]
package com.pritesh.programs;
class Rectangle {
int length;
int width;
Rectangle(int l, int b) {
length = l;
width = b;
}
void area(Rectangle r1) {
int areaOfRectangle = r1.length * r1.width;
System.out.println("Area of Rectangle : "
+ areaOfRectangle);
}
}
class RectangleDemo {
public static void main(String args[]) {
Rectangle r1 = new Rectangle(10, 20);
r1.area(r1);
}
}
我想分享的最后一件事是讲座的这个时刻:记忆分配,我认为它非常有用,以了解Java通过值或更为“通过复制变量的值”如Gevorg所写的。
原始和对象参考,但对象可以改变,如果它们的界面允许。
当您将对象转移到一个方法时,您正在转移一个参考,并且该对象可以通过方法实施进行修改。
void bithday(Person p) {
p.age++;
}
对象本身的参考,通过值:你可以重新分配参数,但变化不会反映:
void renameToJon(Person p) {
p = new Person("Jon"); // this will not work
}
jack = new Person("Jack");
renameToJon(jack);
sysout(jack); // jack is unchanged
作为效应问题,“p”是参考(对象的指标),不能改变。
原始类型通过值,对象的参考也可以被视为原始类型。
为了回报,一切都通过了价值。