когда я передаю переменную, подобную массиву, функции, она создает новое пространство для массива в куче каждый раз, когда я передаю его в качестве параметра другим функциям, или просто использует то же пространство в куче и просто передает ссылку
Java полностью передается по значению , но с массивами и типами объектов передаваемое значение является ссылкой (указателем) на фактический объект, который не дублируется. Поэтому, когда вы передаете массив в функцию, копируется только ссылка ; сам массив не является. Вот почему, если функция изменяет содержимое массива, код, вызывающий функцию, видит изменения.
Пример:
// A method that changes the first entry in an array
void changeArray(String[] theArray) {
theArray[0] = "Updated";
}
// A method that uses the above
void someMethod() {
String[] foo = new String[3];
foo[0] = "Original 0";
foo[1] = "Original 1";
foo[2] = "Original 2";
this.changeArray(foo); // `changeArray` receives a *copy* of the reference
// held in `foo`; both references point to the same
// array
System.out.println(foo[0]); // Prints "Updated"
}
Передача ссылки в метод аналогична присвоению ее другой ссылочной переменной:
String[] foo = new String[3]; // Create a new aaray, assign reference to `foo` variable
String[] bar = foo; // Copy the reference into `bar` as well
foo[0] = "Hi there"; // Use the reference in `foo` to assign to the first element
System.out.println(bar[0]); // Use the reference in `bar`, prints "Hi there"
По сути, ссылки - это значения (числа), которые сообщают JVM, где находятся данные для объекта. Таким образом, даже когда мы копируем ссылку (поскольку Java полностью передается по значению, значение ссылки передается функции), она все равно указывает на ту же память, что и оригинал.
Поскольку ссылка передается в функцию по значению, функция не может изменить ссылку вызывающего кода :
// A method that assigns a new reference; the calling code sees no change
void changeReference(String[] theArray) {
theArray = new String[1]; // Now we're not using the caller's object anymore
theArray[0] = "I was changed";
}
// A method that uses the above
void someMethod() {
String[] foo = new String[3];
foo[0] = "Original 0";
foo[1] = "Original 1";
foo[2] = "Original 2";
this.changeReference(foo);
System.out.println(foo[0]); // Prints "Original 0", our reference wasn't changed
}
Вы заметите, что в точности относится к примитивам:
void whatever(int a) {
a = 5;
}
void someMethod() {
int foo;
foo = 3;
whatever(foo);
System.out.println(foo); // Prints 3, of course, not 5
}
... и фактически, объект ссылки (в отличие от объектов) являются примитивами.
... я должен объявить новый строковый массив или я могу безопасно повторно использовать тот же массив, который содержал нефильтрованный массив, для хранения фильтрованного массива
Вы можете безопасно использовать его повторно, если это уместно в рамках вашей функции. Может быть более целесообразным объявить новую переменную (например, filteredThingy
), но это вопрос стиля и будет зависеть от ситуации.