The story of not knowing the behavior of String by passing Java by reference

What is Java reference passing?

Argument values handled by Java methods are passed by value for basic types and passed by reference for reference types. However, when this story comes up, there are some questions that I don't understand the behavior of String.

Well, I wish I could explain that.

For basic type

For basic types, it is passed by value. So the value is copied and passed. It does not pass the value itself. This means that the value of the passed variable does not change before and after passing it to the method.

//Example 1
public class PrimitiveType {

	public static void main(String[] args) {
		PrimitiveSample ps = new PrimitiveSample();
		int i = 5;
		System.out.println("Value before change of main method: " + i);
		ps.changeInt(i);
		System.out.println("Modified value of main method: " + i);
	}
}

class PrimitiveSample {
	public int changeInt(int i) {
		System.out.println("Value before change with changeInt: " + i);
		i = i + 10;
		System.out.println("Value after change with changeInt: " + i);
		return i;
	}
}
Value before change of main method: 5
Value before change with changeInt: 5
Value after change with changeInt: 15
Modified value of main method: 5

Pass by reference

In the case of the reference type, it is actually "pass by value" because it "copy and pass the referenced address of the reference type".

In other words, if you copy and hand over a memo with "Address of 1 Sakuragaoka-cho, Shibuya-ku, Tokyo" and use the copy of the memo to "Send a letter to the address of 1 Sakuragaoka-cho, Shibuya-ku, Tokyo" , "Address of 1 Sakuragaoka-cho, Shibuya-ku, Tokyo" will receive the letter. However, even if you tear the copy of the memo, it will not affect the "Address of 1 Sakuragaoka-cho, Shibuya-ku, Tokyo".

//Example 2
public class PointerType {

	public static void main(String[] args) {
		StringBuffer sb = new StringBuffer();
		sb.append("AIUEO");
		System.out.println("Value before change of main method: " + sb.toString());
		PointerSample ps = new PointerSample();
		ps.appendData(sb);
		System.out.println("Value before change of main method: " + sb.toString());
		ps.deleteObject(sb);
		System.out.println("The object of the main method does not disappear: " + sb.toString());

	}

}

class PointerSample {
	public void appendData(StringBuffer sb) {
		System.out.println("Value before change in appendData: " + sb.toString());
		sb.append("Kakikukeko");
		System.out.println("Value after change with appendData: " + sb.toString());
	}
	public void deleteObject(StringBuffer sb) {
		sb = null;
	}
}
Value before change of main method:AIUEO
Value before change in appendData:AIUEO
Value changed by appendData:Aiue Okakikukeko
Value before change of main method:Aiue Okakikukeko
The object of the main method does not disappear:Aiue Okakikukeko

So far, I think we've talked about it so far. In the first place, the word "pass by reference" is not good, and "passing by value of the reference destination" is correct, and there are other people who say so. I don't know much about Java, but when I asked someone who was good at C and C ++, he declared, "This is by value." it's interesting.

String or Integer ...

So, when String or Integer comes out, there is a mysterious argument that "Although the reference type is passed by reference, the value of String does not change. This is passed by value", but considering the above story in the first place It all ends with "passing the reference type by value of the reference destination".

To go a little further and explain ** String type has no function to change the object itself **, it is treated as a constant. Same as Integer type. There is no function to modify the object itself. There is no function like List or StringBuffer that "adds a value to your object and changes the contents of the object".

//Example 3 that is not refreshing
public class StringType {
	public static void main(String[] args) {
		StringSample ss = new StringSample();
		String str = "AIUEO";
		System.out.println("Value before change of main method: " + str);
		ss.changeString(str);
		System.out.println("Modified value of main method: " + str);
	}
}

class StringSample {
	public void changeString(String str) {
		System.out.println("Value before change with changeString: " + str);
		str = str + "Kakikukeko";
		System.out.println("Value after change with changeString: " + str);
	}
}
Value before change of main method:AIUEO
Value before change with changeString:AIUEO
Value after change with changeString:Aiue Okakikukeko
Modified value of main method:AIUEO

If you look only at Example 3, it will look the same as Example 1 and you will say "pass by value". In fact, you have to check the contents of str = str +" Kakikukeko ";.

System.identityHashCode (obj) is not a panacea, but it can be used for this kind of research. If you try to incorporate it into your business, you have to keep in mind that there may be duplication, but if the value changes, it is good to see that the object itself has changed.

public class StringType {
	public static void main(String[] args) {
		StringSample ss = new StringSample();
		String str = "AIUEO";
		System.out.println("Value before change of main method: " + str);
		System.out.println("Hash 1 in main:" + System.identityHashCode(str));
		ss.changeString(str);
		System.out.println("Modified value of main method: " + str);
		System.out.println("Hash 2 in main:" + System.identityHashCode(str));
	}
}

class StringSample {
	public void changeString(String str) {
		System.out.println("-------");
		System.out.println("Value before change with changeString: " + str);
		System.out.println("Hash 1 in changeString:" + System.identityHashCode(str));
		System.out.println("-------");
		str = str + "Kakikukeko";
		System.out.println("Value after change with changeString: " + str);
		System.out.println("Hash 2 in changeString:" + System.identityHashCode(str));
		System.out.println("-------");
	}
}
Value before change of main method:AIUEO
Hash 1 in main:2018699554
-------
Value before change with changeString:AIUEO
Hash 1 in changeString:2018699554
-------
Value after change with changeString:Aiue Okakikukeko
Hash 2 in changeString:1311053135
-------
Modified value of main method:AIUEO
Hash 2 in main:2018699554

The hash in main is "2018699554", but in changeString there are "2018699554" and "1311053135". If there is no change in the argument str, it matches the hash value in main, but the object has changed when the str value is changed.

In other words, instead of changing from the original "2018699554", a new object "1311053135" is created and "Aiue Okakikukeko" is referenced there.

This is the same as in Example 2, "Breaking a copy of a note". In terms of str, it's just the difference between "inserting null" and "inserting a new object".

If the String type had a method like "change the value of its own object", it wouldn't have been such a confusing controversy. Conversely, the String type also holds that an object once set is invariant until another object is assigned.

Array ... you ...

I sometimes cry when I say that an array must be passed by value because it is an int type array, but since an array is a real object, it is good to think of it in the same way as other reference types. I don't think it's that difficult if you think of the basic type as a box of objects that can be put inside.

At the end

Passing by reference is not good because it makes the image look like passing the reference value of the object itself. It was a story.

Recommended Posts

The story of not knowing the behavior of String by passing Java by reference
The story of low-level string comparison in Java
[Java] The word passing by reference is bad!
[Java version] The story of serialization
Story of passing Java Gold SE8
The story received by Java SE11 silver
The story of writing Java in Emacs
[Java] [Spring] Test the behavior of the logger
[Java] The story that the expected array was not obtained by the String.split method.
The story of making ordinary Othello in Java
The story of learning Java in the first programming
[Java] Get the length of the surrogate pair string
[Java] The confusing part of String and StringBuilder
[Note] Java: Measures the speed of string concatenation
[Java] Basic summary of Java not covered by Progate ~ Part 1 ~
Check the behavior of Java Intrinsic Locks with bpftrace
Learn the meaning of "passing the PATH" by building a Java development environment on Mac
Story of passing Java Silver SE8 (Oracle Certified Java Programmer, Silver SE 8)
The story of making dto, dao-like with java, sqlite
The story of managing session information by introducing gem Redis
I didn't understand the behavior of Java Scanner and .nextLine ().
About truncation by the number of bytes of String on Android
20190803_Java & k8s on Azure The story of going to the festival
Java beginners briefly summarized the behavior of Array and ArrayList
[Java] Try editing the elements of the Json string using the library
[Java] Basic summary of Java not covered by Progate ~ Part 2 ยท List ~
Traps brought about by the default implementation of the Java 8 interface
Summary of values returned by the Spliterator characteristics method #java
The story of pushing Java to Heroku using the BitBucket pipeline
Handling of java floating point [Note] while reading the reference book
Switch the version of java installed by SDKMAN when moving directories
Part 4: Customize the behavior of OAuth 2.0 Login supported by Spring Security 5
The story that standard output also fatally changes the behavior of the program
The story of toString () starting with passing an array to System.out.println
A story about hitting the League Of Legends API with JAVA
[Java] Appropriate introduction by the people of Tempa Java Part 0 (Code rules)
I tried to summarize the methods of Java String and StringBuilder
The story of stopping because the rails test could not be done
How to check for the contents of a java fixed-length string
The behavior of JS running on `Java SE 8 Nashorn` suddenly changed
[Java] Equivalence comparison where beginners fail in string comparison. You may not even be aware of the mistake! ??
About the behavior of ruby Hash # ==
[Java] Delete the elements of List
Various methods of Java String class
[Java] Output by FormatStyle of DateTimeFormatter
The story of @ViewScoped consuming memory
Arbitrary string creation code by Java
Java pass by value and pass by reference
Various methods of the String class
[Java] Reference / update of Active Directory
Java "pass by reference" problem summary
[Java] Correct comparison of String type
I read the source of String
The origin of Java lambda expressions
The story of making a game launcher with automatic loading function [Java]
The story of acquiring Java Silver in two months from completely inexperienced.
[Java] How to get to the front of a specific string using the String class
The story that the Servlet could not be loaded in the Java Web application
Check the domain by checking the MX record of the email address with java
[Java] Check if the character string is composed only of blanks (= Blank)
<Java> Quiz to batch convert file names separated by a specific character string with a part of the file name